Dashboards e widgets
mad-dash-filters
mad-dashboard-auto-refresh
mad-dashboard-metric-compare
Toolbar de filtros
mad-dash-filters style=toolbar com período (date-range) + categoria — os KPIs abaixo reagem porque usam $that->baseQuery().
Pedidos filtrados
150
SQL Debug — metric_c4fdb117
With inlined binds
select count(tutor_pedidos.id) as total from "tutor_pedidos"
Prepared statement
select count(tutor_pedidos.id) as total from "tutor_pedidos"
Receita filtrada
R$ 689.954,82
SQL Debug — metric_003977e6
With inlined binds
select sum(tutor_pedidos.valor_total) as total from "tutor_pedidos"
Prepared statement
select sum(tutor_pedidos.valor_total) as total from "tutor_pedidos"
resources/views/tutor/examples/dashboards-filtros/toolbar-com-kpis.blade.php
@php
$__component = \Mad\Component\MadRenderContext::getComponent();
@endphp
<mad-dash-filters style="toolbar" name="filtros_toolbar">
<mad-daterange-field name_start="dtIni" name_end="dtFim" label="Período do pedido" presets />
<mad-dbcombo-field name="categoria_id" label="Categoria" database="business"
model="TutorDemoCategoria" display="{nome}" order-by="nome" />
</mad-dash-filters>
<mad-form-grid :cols="2">
<mad-db-metric-card name="filtros_kpi_pedidos" model="TutorDemoPedido" :query="$__component->queryPedidos()"
total="count" label="Pedidos filtrados" icon="shopping-cart" format="integer" />
<mad-db-metric-card name="filtros_kpi_receita" model="TutorDemoPedido" :query="$__component->queryPedidos()"
field="valor_total" total="sum" label="Receita filtrada" icon="circle-dollar-sign" format="money:R$" variant="success" />
</mad-form-grid>
Estilo chips
Mesmo host, mesmos filtros — só troca style=toolbar por style=chips. Os dois blocos desta página compartilham o mesmo estado.
Pedidos (mesmo estado da toolbar acima)
150
SQL Debug — metric_660391eb
With inlined binds
select count(tutor_pedidos.id) as total from "tutor_pedidos"
Prepared statement
select count(tutor_pedidos.id) as total from "tutor_pedidos"
resources/views/tutor/examples/dashboards-filtros/chips.blade.php
@php
$__component = \Mad\Component\MadRenderContext::getComponent();
@endphp
<mad-dash-filters style="chips" name="filtros_chips">
<mad-daterange-field name_start="dtIni" name_end="dtFim" label="Período" presets />
<mad-dbcombo-field name="categoria_id" label="Categoria" database="business"
model="TutorDemoCategoria" display="{nome}" order-by="nome" />
</mad-dash-filters>
<mad-db-metric-card name="filtros_chips_kpi" model="TutorDemoPedido" :query="$__component->queryPedidos()"
total="count" label="Pedidos (mesmo estado da toolbar acima)" icon="filter" />
Comparativo com período anterior
mad-dashboard-metric-compare calcula o delta automaticamente contra comparePeriodQuery().
Receita
R$ 689.954,82
0,0%
vs previous period
Qtde. de pedidos
150
0,0%
vs previous period
resources/views/tutor/examples/dashboards-filtros/comparativo-periodo.blade.php
@php($__component = \Mad\Component\MadRenderContext::getComponent())
<mad-form-grid :cols="2">
<mad-dashboard-metric-compare name="cmp_receita"
:current-query="$__component->queryPedidos()" :compare-query="$__component->comparePedidos()"
model="TutorDemoPedido" field="valor_total" total="sum"
label="Receita" icon="trending-up" format="money:R$" />
<mad-dashboard-metric-compare name="cmp_pedidos"
:current-query="$__component->queryPedidos()" :compare-query="$__component->comparePedidos()"
model="TutorDemoPedido" total="count"
label="Qtde. de pedidos" icon="package" />
</mad-form-grid>
Auto-refresh
mad-dashboard-auto-refresh reexecuta as queries via MadWire a cada N segundos (mínimo 5) — o botão dispara o mesmo handler (onAtualizar) manualmente.
Pedidos (atualiza a cada 15s)
150
SQL Debug — metric_b78cacee
With inlined binds
select count(tutor_pedidos.id) as total from "tutor_pedidos"
Prepared statement
select count(tutor_pedidos.id) as total from "tutor_pedidos"
resources/views/tutor/examples/dashboards-filtros/auto-refresh.blade.php
@php($__component = \Mad\Component\MadRenderContext::getComponent())
<mad-dashboard-auto-refresh :seconds="15" />
<mad-form-grid :cols="2">
<mad-db-metric-card name="auto_refresh_kpi" model="TutorDemoPedido" :query="$__component->queryPedidos()"
total="count" label="Pedidos (atualiza a cada 15s)" icon="refresh-cw" />
<mad-btn variant="outline" size="sm" icon="refresh-ccw" mad:click="onAtualizar">Atualizar agora</mad-btn>
</mad-form-grid>
Código-fonte completo da página
app/control/Tutor/TutorDashboardsFiltros.php
<?php
namespace App\Control\Tutor;
use App\Models\TutorDemo\TutorDemoPedido;
use App\Support\Tutor\TutorCatalog;
use App\Support\Tutor\TutorDemoSeed;
use Illuminate\Database\Eloquent\Builder;
use Mad\Dashboard\MadDashboard;
/**
* TutorDashboardsFiltros — página "Filtros de dashboard" do catálogo.
*
* Estende Mad\Dashboard\MadDashboard (em vez de TutorPage): os 3 tags desta
* página (mad-dash-filters, mad-dashboard-auto-refresh,
* mad-dashboard-metric-compare) só funcionam de verdade sobre um host que
* implementa MadFilterable (baseQuery/comparePeriodQuery/getAutoRefreshSec).
* Herança simples não deixa somar com TutorPage — $catalogKey/view()
* replicam manualmente o pequeno contrato de TutorPage (ver docblock lá).
*/
class TutorDashboardsFiltros extends MadDashboard
{
protected string $catalogKey = 'dashboards_filtros';
protected string $periodType = 'date-range';
protected string $dateField = 'dt_pedido';
/**
* Filtro extra AUTO-DESCOBERTO pelo Mad\Filters\MadFiltersTrait — toda
* public string/array vira filtro automático (discoverFilterProps()),
* aplicado em baseQuery()/comparePeriodQuery() quando a coluna existe no
* model consultado.
*/
public string $categoria_id = '';
protected function onMount(array $params): void
{
TutorDemoSeed::ensure();
}
public function queryPedidos(): Builder
{
return $this->baseQuery(TutorDemoPedido::class);
}
public function comparePedidos(): Builder
{
return $this->comparePeriodQuery(TutorDemoPedido::class);
}
/** Réplica de TutorPage::catalogPage() — ver docblock daquela classe. */
protected function catalogPage(): array
{
$page = TutorCatalog::page($this->catalogKey);
if ($page === null) {
throw new \RuntimeException(
static::class . ': catalogKey [' . $this->catalogKey . '] não existe em TutorCatalog.'
);
}
return $page;
}
protected function view(): string|array
{
return $this->catalogPage()['view'];
}
}
resources/views/tutor/dashboards/filtros.blade.php
<x-tutor-page page="dashboards_filtros">
<x-tutor-demo demo="tutor.examples.dashboards-filtros.toolbar-com-kpis"
title="Toolbar de filtros" desc="mad-dash-filters style=toolbar com período (date-range) + categoria — os KPIs abaixo reagem porque usam $that->baseQuery()." />
<x-tutor-demo demo="tutor.examples.dashboards-filtros.chips"
title="Estilo chips" desc="Mesmo host, mesmos filtros — só troca style=toolbar por style=chips. Os dois blocos desta página compartilham o mesmo estado." />
<x-tutor-demo demo="tutor.examples.dashboards-filtros.comparativo-periodo"
title="Comparativo com período anterior" desc="mad-dashboard-metric-compare calcula o delta automaticamente contra comparePeriodQuery()." />
<x-tutor-demo demo="tutor.examples.dashboards-filtros.auto-refresh"
title="Auto-refresh" desc="mad-dashboard-auto-refresh reexecuta as queries via MadWire a cada N segundos (mínimo 5) — o botão dispara o mesmo handler (onAtualizar) manualmente." />
</x-tutor-page>