Core
Dashboardy
Skládání widgetů na komponentě přes `WithWidgets` a deklarace dashboardu jako vlastníka, kterého najde menu i router.
Na této stránce
- Dashboard layout (WithWidgets)
- Použití
- Blade šablona
- WithWidgets API
- Stav drží hostitel, widgety žádný
- Rozhraní HasWidgets
- Dashboard (deklarovaný, ne komponenta)
- Kde je aplikace registruje
- Jak se vykresluje
- Jak se dostane do menu
- Dashboard API
- Přidání widgetu na dashboard, který nevlastníte
- Související
Dostat widgety na obrazovku jde dvěma způsoby a je to totéž dělení, jaké dělá resource: napsat si je na komponentu, nebo deklarovat dashboard, který je jmenuje, a nechat ho vykreslit stránkou. To druhé je to, co dá položku do menu a URL do routeru, aniž by se kdokoli z nich dozvěděl, co je widget.
Dashboard layout (WithWidgets)
Použijte trait WithWidgets na Livewire komponentě pro složení widgetového dashboardu.
use NyonCode\WireCore\Widgets\Concerns\WithWidgets;use NyonCode\WireCore\Widgets\Contracts\HasWidgets;
Použití
class Dashboard extends Component implements HasWidgets{ use WithWidgets; protected function getWidgets(): array { return [ StatsOverviewWidget::make() ->columns(4) ->stats([ Stat::make('Users', User::count()), Stat::make('Orders', Order::count()), Stat::make('Revenue', "$" . number_format(Order::sum('total'), 2)), Stat::make('Products', Product::count()), ]), ChartWidget::make() ->heading('Monthly Revenue') ->type('line') ->columnSpan(2) ->labels($this->getMonthLabels()) ->datasets($this->getRevenueDatasets()), TableWidget::make() ->heading('Recent Orders') ->table(fn ($table) => $this->configureRecentOrdersTable($table)), ]; } protected function getWidgetColumns(): int { return 2; // 2-sloupcový grid layout }}
Blade šablona
Vykreslete dashboard komponentou <x-wire::widget-grid>.
getVisibleWidgets() je veřejná a vrací jen widgety, které projdou svými
kontrolami viditelnosti a autorizace; každý widget ctí svůj vlastní columnSpan()
a polling interval uvnitř gridu:
<div> <x-wire::widget-grid :widgets="$this->getVisibleWidgets()" :columns="2" /></div>
Každý widget je také Htmlable, takže můžete komponentu přeskočit a rozložit je
sami: @foreach ($this->getVisibleWidgets() as $widget) {{ $widget }} @endforeach.
WithWidgets API
abstract protected function getWidgets(): array // definovat widgetyprotected function getWidgetColumns(): int // sloupce gridu (výchozí: 2)public function getVisibleWidgets(): array // filtrované podle viditelnosti + autorizacepublic function refreshWidget(string $key): void // tik pollingu, zodpovězený tím widgetempublic function filterWidget(string $key, string $value): void // výběr filtrupublic function callWidgetAction(string $key, string $name): void // akce v hlavičcepublic function loadWidget(string $key): void // první render odloženého widgetupublic array $widgetFilters // jaký filtr který widget ukazujepublic array $loadedWidgets // klíče, které už byly staženy
Stav drží hostitel, widgety žádný
Widget je obyčejný objekt, který se z getWidgets() staví znovu při každém
requestu, takže si přes round trip nemůže pamatovat nic. Hostitel může, a dělá
to: zapíše si, jaký filtr který widget ukazuje a které odložené widgety už byly
staženy, a obojí do widgetů vrátí v getVisibleWidgets() — až po orazítkování
klíčů a ještě před dotazem na viditelnost, aby closure ve visible(fn () => …)
mohla přečíst filtr, který uživatel zvolil.
Všechny čtyři metody výše odpovídají markupem jednoho widgetu, stejnou
wire:partial oblastí:
| Spouštěč | Volá | Odpoví |
|---|---|---|
refreshWidget() |
wire:poll na obalu widgetu |
ten widget, překreslený |
filterWidget() |
wire:change na selectu widgetu |
ten widget, znovu vyřešený novým klíčem |
callWidgetAction() |
wire:click na tlačítku v hlavičce |
ten widget, poté co akce doběhla — nebo plný render, když ho akce odstranila |
loadWidget() |
wire:init na obalu odloženého widgetu |
ten widget, poprvé vykreslený |
Klíč, který nic nepojmenuje — widget skrytý od vykreslení stránky, widget bez filtru, widget, který zmizel — nezařadí žádnou oblast a request spadne zpět na plný render, místo aby odpověděl půlkou stránky.
Rozhraní HasWidgets
interface HasWidgets{ public function getWidgets(): array;}
Dashboard (deklarovaný, ne komponenta)
WithWidgets výše dává dashboard dovnitř Livewire komponenty, což stačí,
dokud ho nepotřebuje něco dalšího: komponenta se nedá zaregistrovat, vypsat
v menu ani použít na druhé stránce a její widgety nejsou odnikud jinud
dosažitelné.
Dashboard drží deklaraci sám, stejně jako Resource drží tabulku:
use NyonCode\WireCore\Widgets\Dashboard; final class SalesDashboard extends Dashboard{ public function widgets(): array { return [ StatsOverviewWidget::make()->stats([Stat::make('Tržby', '1.2M')]), ChartWidget::make()->heading('Posledních 30 dní')->type('line'), ]; } public function columns(): int { return 3; }}
php artisan make:wire-dashboard Sales přesně tohle vygeneruje — do
app/Dashboards/, ze stubu, který jde publikovat a upravit:
php artisan vendor:publish --tag=wire-core::stubs
Publikovaný stubs/dashboard.stub má přednost před balíčkovým, stejně jako to
dělá Laravelí stub:publish.
Registruje se stejně jako resources:
// config/wire-core.php'dashboards' => [ App\Dashboards\SalesDashboard::class,],
Kde je aplikace registruje
Dashboardy ani navigační skupiny nepatří žádnému resource ani dashboardu — jsou to věci, které skládá aplikace. wire-core na to dodává provider, stejně jako to dělá Cashier a Fortify:
php artisan vendor:publish --tag=wire-core::providers
Publikuje se jako app/Providers/WireDashboardServiceProvider.php a je váš
k úpravám: zaregistrujte ho v bootstrap/providers.php a deklarujte v něm své
dashboardy i skupiny menu na jednom místě.
Jak se vykresluje
WirePanels\Resources\Pages\DashboardPage ho vykreslí přesně tak, jako
ListPage vykresluje tabulku resource — skládá WithWidgets, takže mřížka,
pravidla viditelnosti i polling jednotlivých widgetů výše zůstávají beze změny:
use NyonCode\WirePanels\Resources\Pages\DashboardPage; class SalesDashboardPage extends DashboardPage{ protected static ?string $dashboard = SalesDashboard::class;}
Obě cesty zůstávají rovnocenné: stránka, která si deklaruje vlastní
getWidgets() a žádný dashboard nejmenuje, funguje jako dřív. Stránka, která
nedeklaruje ani jedno, se odmítne vykreslit místo prázdné mřížky — prázdná se
čte jako „žádné widgety“, ne jako chyba.
Jak se dostane do menu
Dashboard se do menu dostane stejně jako resource — implementací
ProvidesNavigation:
public static function navigation(): NavigationItem{ return NavigationItem::make('Prodej')->icon('outline:chart-bar')->group('insights');}
Workspace přitom vůbec neví, co je dashboard. DashboardRegistry je
RegistrySource a workspace vypisuje to, co mu katalog podá — díky tomu může
menu míchat resources, dashboardy a cokoli, co aplikace zaregistruje později.
Router čte tentýž katalog, takže dashboard, který deklaruje pages(), zaroutuje
Route::wireResources() stejně jako resource.
Viz Resources.
Dashboard API
| Metoda | Vrací | K čemu |
|---|---|---|
widgets(): array |
array<int, Widget> |
Widgety v pořadí rozložení. Povinné |
columns(): int |
int |
Sloupce mřížky; výchozí 2 |
static key(): string |
string |
Identita, odvozená z názvu třídy bez Dashboard |
static label(): string |
string |
Lidský název; výchozí nadpis stránky |
Přidání widgetu na dashboard, který nevlastníte
Dashboard z nainstalovaného modulu deklaruje svoje
widgety uvnitř balíčku, takže aplikace k nim přidá přes
hook widget.configuring:
$manager->hook(Hook::WidgetConfiguring, function (WidgetConfiguringPayload $payload) { $payload->widgets[] = StatsOverviewWidget::make()->stats([Stat::make('Otevřené', '12')]); return $payload;}, for: 'sales');
for: pojmenuje klíč, pod kterým se dashboard zaregistroval — DashboardPage jím
odpoví. Stránka, která si widgety deklaruje sama, neukazuje nic registrovaného
a zúží se podle třídy.
Běží dřív, než se orazítkují klíče, a dřív, než seznam profiltruje viditelnost
— a obojí je podstatné: klíč widgetu se odvozuje z jeho indexu v neprofiltrovaném
seznamu, takže widget přidaný později by žádný neměl (a poll tick by ho nedosáhl),
nebo by si vzal ten, na který už jiný widget slyší; a visible() přidaného widgetu
platí, místo aby se přeskočilo.
Související
- Widgety — to, co se skládá
- Panely: Stránky —
DashboardPage, komponenta, která deklarovaný dashboard vykreslí - Panely: Navigace — jak se dashboard dostane do menu
- Panely: Moduly — deklarace dashboardů oblasti spolu s jejími resourcy