Docs›Componentes (Admin)›mad-tree-view
Componentes (Admin)

mad-tree-view

Árvore hierárquica com expand/collapse.

Componente de arvore hierarquica com expand/collapse, context menu por no, badges, persistencia de estado e operacoes parciais via MadResponse.

Tag compilada pelo MadGridCompiler.

Props

Prop Tipo Default Descricao
name string '' Identificador (ops, localStorage, DOM)
model string '' Classe model Eloquent para auto-query
database string MAIN_DATABASE Conexao do banco
display string 'nome' Campo ou template {nome} ({codigo})
key string 'id' Campo PK
parent-field string 'parent_id' Campo que referencia o pai
icon string 'file' Icone Lucide padrao
active-icon string '' Icone quando selecionado
expanded-icon string '' Icone quando expandido com filhos
icon-field string '' Campo do model para icone por no
order-by string display Campo de ordenacao
filters array [] Filtros (mesma sintaxe do dbcombo): [['campo', 'op', 'val'], ...]
items array null Dados manuais (dispensa model)
active string '' ID do no ativo/selecionado
count-field string '' Campo do model para badge de contagem
mad:click string '' Metodo PHP ao clicar no (recebe ID)
expanded string 'all' Estado inicial: all, none, first
persist bool false Persistir expand state em localStorage
class string '' Classes CSS extras

Tags filhas

<mad-tree-actions position="top|bottom">

Botoes globais acima ou abaixo da arvore. Conteudo e HTML/Blade livre.

<mad-tree-actions position="top">
    <mad-btn navigate="CategoriaForm" variant="ghost" size="sm" icon="plus">Nova Categoria</mad-btn>
</mad-tree-actions>

<mad-tree-context-menu>

Template de context menu aplicado a cada no. Suporta placeholders {id}, {name}, {label} e qualquer campo do model.

<mad-tree-context-menu>
    <mad-menu-item icon="pencil" navigate="CategoriaForm::onEdit({id})">Editar</mad-menu-item>
    <mad-menu-separator />
    <mad-menu-item icon="trash-2" variant="danger" mad:click="onDelete({id})">Excluir</mad-menu-item>
</mad-tree-context-menu>

Uso com model (auto-query)

<mad-tree-view name="pastas" model="GedFolder" database="communication"
    display="name" parent-field="parent_id"
    icon="folder" active-icon="folder-open"
    order-by="name" :active="$folderId"
    count-field="_document_count"
    mad:click="onSelectFolder" persist>

    <mad-tree-context-menu>
        <mad-menu-item icon="folder-plus" navigate="GedFolderForm" params="{parent_id: {id}}">
            Nova subpasta
        </mad-menu-item>
        <mad-menu-separator />
        <mad-menu-item icon="pencil" navigate="GedFolderForm::onEdit({id})">Editar</mad-menu-item>
        <mad-menu-item icon="trash-2" variant="danger" mad:click="onDeleteFolder({id})">Excluir</mad-menu-item>
    </mad-tree-context-menu>
</mad-tree-view>

Uso com dados manuais

@php
    $tree = [
        ['id' => 1, 'name' => 'Raiz A', 'icon' => 'folder', '_count' => 5, 'children' => [
            ['id' => 2, 'name' => 'Sub A1', 'icon' => 'folder', '_count' => 3, 'children' => []],
        ]],
        ['id' => 3, 'name' => 'Raiz B', 'icon' => 'file', '_count' => 0, 'children' => []],
    ];
@endphp
<mad-tree-view name="categorias" :items="$tree" display="name"
    icon="folder" count-field="_count" mad:click="onSelect" persist />

Estrutura do array: ['id', 'name', 'icon'?, 'children'?, '{count-field}'?]

MadResponse — Operacoes parciais

Adicionar no

return (new MadResponse())
    ->treeAddNode('pastas', [
        'id'        => $folder->id,
        'parent_id' => $folder->parent_id,
        'name'      => $folder->name,
        'icon'      => 'folder',
    ])
    ->toast('Pasta criada!', 'success')
    ->closeDrawer();

Remover no (com animacao)

return (new MadResponse())
    ->treeRemoveNode('pastas', $folderId)
    ->toast('Pasta excluida', 'success');

Atualizar no (label, icone, badge)

return (new MadResponse())
    ->treeUpdateNode('pastas', $folderId, [
        'name'  => $novoNome,
        'icon'  => 'folder-lock',
        'count' => 42,
    ]);

Mudar no ativo

return (new MadResponse())
    ->treeSetActive('pastas', $folderId);

Icones dinamicos

{{-- Icone muda quando selecionado --}}
<mad-tree-view icon="folder" active-icon="folder-open" ...>

{{-- Icone muda quando expandido --}}
<mad-tree-view icon="folder" expanded-icon="folder-open" ...>

{{-- Icone por no (campo do model) --}}
<mad-tree-view icon-field="icone" ...>

Persistencia de estado

Com persist, o estado de expand/collapse e salvo em localStorage com a key mad-tree-{name}-expanded. Restaura automaticamente ao recarregar.

Filtros

A prop :filters e o UNICO mecanismo de filtro do <mad-tree-view> — um array de tuplas [campo, operador, valor] aplicado direto no Eloquent Builder do model (Mad\Database\QuerySource::applyArrayFilters()). Nao existe prop :criteria — qualquer valor passado nela e silenciosamente ignorado pelo compilador.

{{-- Filtro simples (1 condicao) --}}
<mad-tree-view name="categorias" model="Categoria" display="nome"
    :filters="[['ativo', '=', '1']]" />

{{-- Multiplas condicoes (AND implicito) --}}
<mad-tree-view name="categorias" model="Categoria" display="nome"
    :filters="[['ativo', '=', '1'], ['tipo', '=', 'produto']]" />

{{-- Operadores: '=', '>', '<', '>=', '<=', '<>', 'in', 'not in', 'is null', 'is not null' --}}
<mad-tree-view name="pastas" model="GedFolder" display="name"
    :filters="[['owner_id', 'in', $ownerIds]]" />

{{-- Filtro dinamico vindo de outra parte da tela --}}
<mad-tree-view name="categorias" model="Categoria" display="nome"
    :filters="[['empresa_id', '=', $this->empresaId]]" />

Para uma fonte mais elaborada que :filters nao cobre (joins, subqueries, scopes do model), monte o array fora do componente reaproveitando um Eloquent Builder normal — sem nenhuma classe de criterio dedicada:

@php
    $ativos = Categoria::ativas()->pluck('id')->all(); // scope do model, por exemplo
@endphp
<mad-tree-view name="categorias" model="Categoria" display="nome"
    :filters="[['id', 'in', $ativos]]" />

NUNCA fazer

{{-- ERRADO: montar arvore manualmente com @foreach recursivo --}}
@foreach($folders as $f)
    <div style="padding-left:{{ $depth * 14 }}px;">{{ $f->name }}</div>
    @if($f->children)
        @include('partials.tree-item', ['items' => $f->children, 'depth' => $depth + 1])
    @endif
@endforeach

{{-- CERTO --}}
<mad-tree-view name="pastas" model="GedFolder" display="name" parent-field="parent_id"
    icon="folder" mad:click="onSelect" />

{{-- ERRADO: buscar a arvore no controller e passar :criteria/objeto de query --}}
@php $crit = Categoria::where('ativo', '1'); @endphp
<mad-tree-view name="categorias" :criteria="$crit" />
{{-- :criteria nao existe — o compilador ignora a prop silenciosamente --}}

{{-- CERTO: usar model + :filters (array-DSL) --}}
<mad-tree-view name="categorias" model="Categoria" display="nome" parent-field="parent_id"
    :filters="[['ativo', '=', '1']]" />

{{-- ERRADO: recarregar a arvore inteira apos criar/editar/excluir --}}
$this->loadData(); // full re-render

{{-- CERTO: ops parciais --}}
return (new MadResponse())->treeAddNode('pastas', [...]);
return (new MadResponse())->treeRemoveNode('pastas', $id);
return (new MadResponse())->treeUpdateNode('pastas', $id, ['name' => $nome]);