# Configuração no controller

Para habilitar o sistema de ordenação em um módulo, é necessário implementar no **controller** uma função pública chamada **orderConfig()**  
Essa função é responsável por retornar duas arrays principais que controlam todo o comportamento da ordenação: **$generalConfig e $configLevels**.

#### <span style="color: rgb(0, 0, 0);">**$generalConfig**</span>

A array **$generalConfig** contém configurações gerais da ordenação.  
Atualmente, possui as seguintes propriedades possíveis:

```
$generalConfig = ['selfGroupedRecords' => false];
```

<table class="w-fit min-w-(--thread-content-width)" data-end="926" data-start="690" id="bkmrk-propriedade-tipo-des" style="width: 100%; height: 94.8126px;"><thead data-end="724" data-start="690"><tr data-end="724" data-start="690" style="height: 47.5938px;"><th data-col-size="sm" data-end="704" data-start="690" style="width: 20.143%; height: 47.5938px;">Propriedade</th><th data-col-size="sm" data-end="711" data-start="704" style="width: 11.4469%; height: 47.5938px;">Tipo</th><th data-col-size="lg" data-end="724" data-start="711" style="width: 68.4101%; height: 47.5938px;">Descrição</th></tr></thead><tbody data-end="926" data-start="762"><tr><td style="width: 20.143%;">**view**</td><td style="width: 11.4469%;">**string | null**</td><td style="width: 68.4101%;">Para alterar a view que será exibida a ordenação, pode ser passado um nome de rota (por exemplo, "*panel.layouts.modules.order*")

</td></tr><tr data-end="926" data-start="762" style="height: 47.2188px;"><td class="align-left" data-col-size="sm" data-end="789" data-start="762" style="width: 20.143%; height: 47.2188px;"> **selfGroupedRecords**</td><td class="align-left" data-col-size="sm" data-end="798" data-start="789" style="width: 11.4469%; height: 47.2188px;">**bool**</td><td data-col-size="lg" data-end="926" data-start="798" style="width: 68.4101%; height: 47.2188px;">Define se a ordenação será **recursiva dentro do mesmo módulo** (por exemplo, quando um registro pode ter outro como “pai”).

</td></tr></tbody></table>

#### **<span style="color: rgb(0, 0, 0);">$configLevels</span>**

A array **$configLevels** é onde é definida toda a **lógica de ordenação**.  
Cada item dentro dela representa um **nível de ordenação** — ou seja:

- Se for uma ordenação **simples** (sem níveis adicionais ou recursivos), haverá **apenas um nível**.
- Se for uma ordenação **hierárquica** (por exemplo, *seção → produto*), haverá **um nível para cada relação**.

> **Observações:**
> 
> - A **ordem dos itens na array** define a hierarquia dos níveis.  
>     O **primeiro item** representa o **primeiro nível** da ordenação, o **segundo item** o **segundo nível**, e assim por diante.
> - A chave de cada nível deve ser um **identificador em camelCase**, de preferência o nome do módulo.

Cada nível da configuração deve conter as seguintes propriedades:

```
 $configLevels = [

            'levelOne' => [
                'label' => 'Nivel 1',
                'model' => SubmodulesTest::class,
                'sortable' => true,
                'labelBtnNextLevel' => 'Ordernar itens do nível 1',
                'breadcrumbColumnName' => 'name',
                'order' => ['column' => 'order', 'type' => 'ASC'],
                'AdditionalQuery' => function ($q) { $q->where('id', 1); },
                'columnsToList' => [
                    [
                        'name' => 'active',
                        'label' => 'Status'
                    ],
                    [
                        'name' => 'id',
                        'label' => '#'
                    ],
                    [
                        'name' => 'name',
                        'label' => 'Título'
                    ],
                ],
            ],
            'levelTwo' => [
                'label' => 'Nivel 2',
                'model' => NivelDoi::class,
                'sortable' => true,
                'order' => ['column' => 'order', 'type' => 'ASC'],
                'breadcrumbColumnName' => 'name',
                'columnsToList' => [
                    [
                        'name' => 'active',
                        'label' => 'Status'
                    ],
                    [
                        'name' => 'id',
                        'label' => '#'
                    ],
                    [
                        'name' => 'name',
                        'label' => 'Título'
                    ],
                ],
            ],
            // Adicione mais níveis aqui, se necessário
        ];
```

<table class="w-fit min-w-(--thread-content-width)" data-end="2450" data-start="1571" id="bkmrk-propriedade-tipo-des-1" style="width: 105%; height: 338.172px;"><thead data-end="1605" data-start="1571"><tr data-end="1605" data-start="1571" style="height: 29.7969px;"><th data-col-size="sm" data-end="1585" data-start="1571" style="width: 22.8464%; height: 29.7969px;">Propriedade</th><th data-col-size="sm" data-end="1592" data-start="1585" style="width: 12.2347%; height: 29.7969px;">Tipo</th><th data-col-size="lg" data-end="1605" data-start="1592" style="width: 64.794%; height: 29.7969px;">Descrição</th></tr></thead><tbody data-end="2450" data-start="1643"><tr data-end="1697" data-start="1643" style="height: 29.7969px;"><td class="align-left" data-col-size="sm" data-end="1657" data-start="1643" style="width: 22.8464%; height: 29.7969px;">**label**</td><td class="align-left" data-col-size="sm" data-end="1668" data-start="1657" style="width: 12.2347%; height: 29.7969px;">**string**</td><td data-col-size="lg" data-end="1697" data-start="1668" style="width: 64.794%; height: 29.7969px;">Nome descritivo do nível.</td></tr><tr data-end="1769" data-start="1698" style="height: 30.1094px;"><td data-col-size="sm" data-end="1712" data-start="1698" style="width: 22.8464%; height: 30.1094px;">**model**</td><td data-col-size="sm" data-end="1722" data-start="1712" style="width: 12.2347%; height: 30.1094px;">**Model**</td><td data-col-size="lg" data-end="1769" data-start="1722" style="width: 64.794%; height: 30.1094px;">Instância da model correspondente ao nível.</td></tr><tr data-end="1861" data-start="1770" style="height: 30.1094px;"><td data-col-size="sm" data-end="1787" data-start="1770" style="width: 22.8464%; height: 30.1094px;">**sortable**</td><td data-col-size="sm" data-end="1796" data-start="1787" style="width: 12.2347%; height: 30.1094px;">**bool**</td><td data-col-size="lg" data-end="1861" data-start="1796" style="width: 64.794%; height: 30.1094px;">Define se o nível atual pode ser ordenado (**true** / **false**).</td></tr><tr data-end="1967" data-start="1862" style="height: 46.5938px;"><td data-col-size="sm" data-end="1888" data-start="1862" style="width: 22.8464%; height: 46.5938px;">**labelBtnNextLevel**</td><td data-col-size="sm" data-end="1899" data-start="1888" style="width: 12.2347%; height: 46.5938px;">**string**

*(opcional)*

</td><td data-col-size="lg" data-end="1967" data-start="1899" style="width: 64.794%; height: 46.5938px;">Texto exibido no botão que permite avançar para o próximo nível.</td></tr><tr data-end="2058" data-start="1968" style="height: 47.2188px;"><td data-col-size="sm" data-end="1997" data-start="1968" style="width: 22.8464%; height: 47.2188px;">**breadcrumbColumnName**</td><td data-col-size="sm" data-end="2008" data-start="1997" style="width: 12.2347%; height: 47.2188px;">**string**</td><td data-col-size="lg" data-end="2058" data-start="2008" style="width: 64.794%; height: 47.2188px;">Coluna usada para exibir o nome no breadcrumb.</td></tr><tr data-end="2165" data-start="2059" style="height: 30.1094px;"><td data-col-size="sm" data-end="2073" data-start="2059" style="width: 22.8464%; height: 30.1094px;">**order**</td><td data-col-size="sm" data-end="2083" data-start="2073" style="width: 12.2347%; height: 30.1094px;">**array**</td><td data-col-size="lg" data-end="2165" data-start="2083" style="width: 64.794%; height: 30.1094px;">Define a ordenação padrão da listagem (**\['column' =&gt; 'id', 'type' =&gt; 'asc'\]**).</td></tr><tr data-end="2340" data-start="2166" style="height: 47.2188px;"><td data-col-size="sm" data-end="2187" data-start="2166" style="width: 22.8464%; height: 47.2188px;">**columnToList**</td><td data-col-size="sm" data-end="2197" data-start="2187" style="width: 12.2347%; height: 47.2188px;">**array**</td><td data-col-size="lg" data-end="2340" data-start="2197" style="width: 64.794%; height: 47.2188px;">Define as colunas exibidas na listagem de ordenação. Cada item deve conter **name** (coluna no banco) e **label** (rótulo exibido no frontend).</td></tr><tr data-end="2450" data-start="2341" style="height: 47.2188px;"><td data-col-size="sm" data-end="2365" data-start="2341" style="width: 22.8464%; height: 47.2188px;">**additionalQuery**</td><td data-col-size="sm" data-end="2390" data-start="2365" style="width: 12.2347%; height: 47.2188px;">**closure**

*(opcional)*

</td><td data-col-size="lg" data-end="2450" data-start="2390" style="width: 64.794%; height: 47.2188px;">Permite aplicar filtros adicionais na query de listagem.</td></tr></tbody></table>

> **Observação:**
> 
> Na propriedade **columnToList**, é possível exibir campos que venham de relações da model.  
> Para isso, basta referenciar o campo desejado como **string**, utilizando o nome da relação seguido do nome da coluna.
> 
> **Exemplo:**
> 
> ```
> ['name' => 'parent->title', 'label' => 'Seção Pai']
> ```
> 
> <div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div class="sticky top-9"><div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"><div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs">  
> </div></div></div><div class="overflow-y-auto p-4" dir="ltr">Nesse caso, **parent** representa o nome da relação definida na model, e **nome** é o campo que será exibido no componente de ordenação.</div></div>

### **Exemplo:**

```php
public function orderConfig()
    {
        $generalConfig = ['selfGroupedRecords' => false];

        $configLevels = [

            'author' => [
                'label' => 'Autores',
                'model' => Author::class,
                'sortable' => true,
                'order' => ['column' => 'order', 'type' => 'ASC'],
                'breadcrumbColumnName' => 'title',
                'columnsToList' => [
                    [
                        'name' => 'active',
                        'label' => 'Status'
                    ],
                    [
                        'name' => 'id',
                        'label' => '#'
                    ],
                    [
                        'name' => 'name',
                        'label' => 'Título'
                    ],
                ],
            ],
            // Adicione mais níveis aqui, se necessário
        ];

        return ['generalConfig' => $generalConfig, 'configLevels' => $configLevels];
    }
```

### **Definindo a ordem no <span style="text-decoration: underline;">store</span>**

No método **store** (ou equivalente) do controller, a coluna **order** deve ser preenchida automaticamente com o **próximo valor de ordem** disponível, utilizando o método getNextOrder() da trait.

Esse método retorna o próximo valor de posição com base no contexto atual.  
Se for necessário aplicar um filtro (por exemplo, ordenar apenas dentro de um determinado nível), o método aceita uma **Closure** como segundo parâmetro:

**Exemplo:**

Nesse caso, o sistema calcula automaticamente o próximo valor com base em todos os registros existentes no módulo atual.

```php
$model->order = $model->getNextOrder();
```

**Exemplo com filtro de nível (recomendado para estruturas hierárquicas):**

Quando a ordenação depende de outro nível — como no caso **seção → produto**, em que os produtos devem ser ordenados apenas dentro de uma determinada seção —  
é obrigatório utilizar uma **Closure** para filtrar o contexto antes de calcular a próxima posição.

```
$model->order = $model->getNextOrder(function ($query) use ($secao_id) {
    return $query->where('secao_id', $secao_id);
});
```