From d97b8bdf49eb74b73a6e667bcc38b2724786ec02 Mon Sep 17 00:00:00 2001 From: LT Date: Thu, 27 Jun 2024 14:40:03 +0300 Subject: [PATCH] feat: Spa prototype --- src/Laravel/Layouts/AppLayout.php | 46 +++++++++++-------- src/Laravel/Layouts/CompactLayout.php | 29 ++++++------ .../Providers/MoonShineServiceProvider.php | 14 ++++++ .../Resource/ResourceModelCrudRouter.php | 9 +++- src/MenuManager/MenuElement.php | 2 + 5 files changed, 65 insertions(+), 35 deletions(-) diff --git a/src/Laravel/Layouts/AppLayout.php b/src/Laravel/Layouts/AppLayout.php index d841156f0..4f871f070 100644 --- a/src/Laravel/Layouts/AppLayout.php +++ b/src/Laravel/Layouts/AppLayout.php @@ -5,11 +5,13 @@ namespace MoonShine\Laravel\Layouts; use MoonShine\Laravel\Components\Layout\{Flash, Locales, Notifications, Profile, Search}; +use MoonShine\Laravel\Components\Fragment; use MoonShine\Laravel\Resources\MoonShineUserResource; use MoonShine\Laravel\Resources\MoonShineUserRoleResource; use MoonShine\MenuManager\MenuGroup; use MoonShine\MenuManager\MenuItem; -use MoonShine\UI\Components\{Breadcrumbs, +use MoonShine\UI\Components\{ActionButton, + Breadcrumbs, Components, Layout\Block, Layout\Body, @@ -27,6 +29,8 @@ Layout\Wrapper, Title, When}; +use MoonShine\Support\AlpineJs; +use MoonShine\Support\Enums\JsEvent; use MoonShine\UI\MoonShineLayout; class AppLayout extends MoonShineLayout @@ -38,11 +42,11 @@ protected function menu(): array MenuItem::make( static fn () => __('moonshine::ui.resource.admins_title'), moonshine()->getContainer(MoonShineUserResource::class) - ), + )->spa(), MenuItem::make( static fn () => __('moonshine::ui.resource.role_title'), moonshine()->getContainer(MoonShineUserRoleResource::class) - ), + )->spa(), ]), ]; } @@ -91,28 +95,30 @@ public function build(): LayoutBuilder ])->collapsed(), Block::make([ - Flash::make(), - Header::make([ - Breadcrumbs::make($this->getPage()->getBreadcrumbs()) - ->prepend(moonshineRouter()->getEndpoints()->home(), icon: 'home'), + Fragment::make([ + Flash::make(), + Header::make([ + Breadcrumbs::make($this->getPage()->getBreadcrumbs()) + ->prepend(moonshineRouter()->getEndpoints()->home(), icon: 'home'), - Search::make(), + Search::make(), - When::make( - static fn (): bool => moonshineConfig()->isAuthEnabled() && moonshineConfig()->isUseNotifications(), - static fn (): array => [Notifications::make()] - ), + When::make( + static fn (): bool => moonshineConfig()->isAuthEnabled() && moonshineConfig()->isUseNotifications(), + static fn (): array => [Notifications::make()] + ), - Locales::make(), - ]), + Locales::make(), + ]), - Content::make([ - Title::make($this->getPage()->getTitle())->class('mb-6'), + Content::make([ + Title::make($this->getPage()->getTitle())->class('mb-6'), - Components::make( - $this->getPage()->getComponents() - ), - ]), + Components::make( + $this->getPage()->getComponents() + ), + ]), + ])->name('_content')->customAttributes(['id' => 'content']), Footer::make() ->copyright(static fn (): string => sprintf( diff --git a/src/Laravel/Layouts/CompactLayout.php b/src/Laravel/Layouts/CompactLayout.php index c5acbe4a6..1c7dc93bd 100644 --- a/src/Laravel/Layouts/CompactLayout.php +++ b/src/Laravel/Layouts/CompactLayout.php @@ -25,6 +25,7 @@ Layout\TopBar, Layout\Wrapper, When}; +use MoonShine\Laravel\Components\Fragment; class CompactLayout extends AppLayout { @@ -158,23 +159,25 @@ public function build(): LayoutBuilder ]), ])->collapsed(), Block::make([ - Flash::make(), - Header::make([ - Breadcrumbs::make($this->getPage()->getBreadcrumbs()) - ->prepend(moonshineRouter()->getEndpoints()->home(), icon: 'home'), + Fragment::make([ + Flash::make(), + Header::make([ + Breadcrumbs::make($this->getPage()->getBreadcrumbs()) + ->prepend(moonshineRouter()->getEndpoints()->home(), icon: 'home'), - Search::make(), + Search::make(), - Notifications::make(), + Notifications::make(), - Locales::make(), - ]), + Locales::make(), + ]), - Content::make([ - Components::make( - $this->getPage()->getComponents() - ), - ]), + Content::make([ + Components::make( + $this->getPage()->getComponents() + ), + ]), + ])->name('_content')->customAttributes(['id' => 'content']), Footer::make() ->copyright(static fn (): string => sprintf( diff --git a/src/Laravel/Providers/MoonShineServiceProvider.php b/src/Laravel/Providers/MoonShineServiceProvider.php index d1878f5e0..e4e12fed1 100644 --- a/src/Laravel/Providers/MoonShineServiceProvider.php +++ b/src/Laravel/Providers/MoonShineServiceProvider.php @@ -52,11 +52,14 @@ use MoonShine\Laravel\MoonShineConfigurator; use MoonShine\Laravel\MoonShineRequest; use MoonShine\Laravel\Resources\ModelResource; +use MoonShine\Laravel\Resources\MoonShineUserRoleResource; use MoonShine\Laravel\Storage\LaravelStorage; +use MoonShine\MenuManager\MenuItem; use MoonShine\MenuManager\MenuManager; use MoonShine\MoonShine; use MoonShine\Support\Enums\Env; use MoonShine\UI\Applies\AppliesRegister; +use MoonShine\UI\Components\ActionButton; use MoonShine\UI\Contracts\Collections\FieldsCollection; use MoonShine\UI\Fields\Checkbox; use MoonShine\UI\Fields\Date; @@ -181,6 +184,17 @@ protected function registerBindings(): self old: static fn (string $key, mixed $default) => session()->getOldInput($key, $default) )); + MenuItem::macro('spa', function () { + /** @var ModelResource $filler */ + $filler = value($this->getFiller()); + + return $this->setUrl( + fn() => $filler->getFragmentLoadUrl('_content') + )->changeButton( + static fn(ActionButton $btn) => $btn->async(selector: '#content') + ); + }); + return $this; } diff --git a/src/Laravel/Traits/Resource/ResourceModelCrudRouter.php b/src/Laravel/Traits/Resource/ResourceModelCrudRouter.php index 6dbd6446d..a9a76f74a 100644 --- a/src/Laravel/Traits/Resource/ResourceModelCrudRouter.php +++ b/src/Laravel/Traits/Resource/ResourceModelCrudRouter.php @@ -5,6 +5,7 @@ namespace MoonShine\Laravel\Traits\Resource; use Illuminate\Database\Eloquent\Model; +use MoonShine\Core\Contracts\PageContract; use MoonShine\Core\Contracts\ResourceContract; use MoonShine\Laravel\Pages\Page; use MoonShine\Support\Enums\PageType; @@ -77,10 +78,14 @@ public function getDetailPageUrl( public function getFragmentLoadUrl( string $fragment, - Page $page, - Model|int|string|null $model, + ?PageContract $page = null, + Model|int|string|null $model = null, array $params = [] ): string { + if(is_null($page)) { + $page = $this->getIndexPage(); + } + return $this->getPageUrl( $page, params: array_filter([ diff --git a/src/MenuManager/MenuElement.php b/src/MenuManager/MenuElement.php index 9226e2746..1316064b6 100644 --- a/src/MenuManager/MenuElement.php +++ b/src/MenuManager/MenuElement.php @@ -5,6 +5,7 @@ namespace MoonShine\MenuManager; use Closure; +use Illuminate\Support\Traits\Macroable; use MoonShine\Support\Components\MoonShineComponentAttributeBag; use MoonShine\Support\Traits\HasCanSee; use MoonShine\Support\Traits\Makeable; @@ -17,6 +18,7 @@ abstract class MenuElement implements MoonShineRenderable, HasCanSeeContract { + use Macroable; use Makeable; use WithComponentAttributes; use WithIcon;