Que una entrada se muestre lo decide show(). Tanto los inputs como los filtros lo incluyen, y Laravel Front lo respeta igual en ambos casos: un filtro con show(false) no se renderiza, no se aplica a la consulta y no se cuenta entre los filtros activos.
No decidas su pertenencia en el array en su lugar. Un resource que añade u omite una entrada para ocultarla ha movido una decisión de visibilidad a la forma de fields() o filters(), donde quien lee el código ya no puede verla junto al campo al que afecta.
// Wrong
return [
Inputs\Text::make('Name'),
...(billingAvailable() ? app('billing.user-resource')->fields($this) : []),
];
// Wrong
public function filters()
{
return billingAvailable()
? app('billing.user-resource')->filters()
: [];
}
// Correct
return [
Inputs\Text::make('Name'),
Inputs\Text::make('Current Plan', 'current_plan_name')->show(billingUser() !== null),
];
El resource anfitrión es dueño de su propia lista. Un paquete opcional aporta una entrada mediante una llamada que hace el resource — billingUser()?->addonsPanel($this) se lee como una sola entrada en el array, mantiene la lógica del paquete dentro del paquete y conserva la entrada en la posición que eligió el resource. Un paquete puede incluir resources para sus propios modelos; no debe proporcionar los fields, filters ni el orden de un resource que pertenece a la aplicación anfitriona.
Construir una entrada no es lo mismo que mostrarla. show() decide la visualización, y se evalúa después de que la entrada se construye. Una entrada cuya construcción no es segura — consulta las tablas de un paquete opcional o nombra una clase que quizá no esté instalada — ya se habrá ejecutado para entonces.
En su lugar, haz que la construcción sea inerte, para que show() pueda hacerse cargo de la decisión. Las opciones de un filtro son el caso habitual: pasa un closure y resuélvelo cuando se construya el field, lo que solo ocurre con filtros que hayan pasado show().
// Correct — nothing runs unless the filter is shown
(new Filters\SelectFilter)
->setTitle(__('Plan'), 'plan', 'plan')
->options(function () {
return collect(['' => __('All')])->merge(billingCoreModel('plan')::pluck('name', 'id'));
})
->setScope('byPlan')
->show(billingUser() && billingCoreModel('plan')::isActive()),
Cuando la construcción no puede diferirse, protégela con un retorno temprano al principio del método. Esa protección indica que la entrada no puede construirse, que es una afirmación distinta de decir que la entrada debería ocultarse, y mantiene la condición fuera del array.