MoonShine v.2.4 "Midnight Jubilee"

MoonShine v.2.4 "Midnight Jubilee"

Danil Shutsky
Danil Shutsky
10.12.2023 в 14:19

На этой неделе команда MoonShine выпустила релиз v2.4.0 с кодовым именем "Midnight Jubilee"! Давайте взглянем на самое интересное в этом обновлении!

Профиль вынесен в LayoutBuilder

BREAKING CHANGE - Теперь Profile не жестко задан в Sidebar, а вынесен в LayoutBuilder. Это изменение даст больше возможностей для кастомизации шаблона, но при обновлении если вы публиковали собственный LayoutBuilder, то вам также будет необходимо добавить в Sidebar компонент Profile:

Sidebar::make([
    Menu::make()->customAttributes(['class' => 'mt-2']),
    Profile::make(withBorder: true),
]),

Или в TopBar:

TopBar::make([
    Menu::make()->top(),
])->actions([
    Profile::make()
]),

Подробности в PR

Scout поиск

Добавили глобальный поиск на основе интеграции с Laravel Scout.

Необходимо указать перечень моделей для поиска и реализовать интерфейс в моделях:

// config/moonshine.php

'global_search' => [
    Article::class,
    User::class
],

Пример модели:

use MoonShine\Scout\HasGlobalSearch;
use MoonShine\Scout\SearchableResponse;
use Laravel\Scout\Searchable;
use Laravel\Scout\Builder;

class Article extends Model implements HasGlobalSearch
{
    use Searchable;

    public function searchableQuery(Builder $builder): Builder
    {
        return $builder->take(4);
    }

    public function toSearchableResponse(): SearchableResponse
    {
        return new SearchableResponse(
            group: 'Articles',
            title: $this->title,
            url: '/',
            preview: $this->text,
            image: $this->thumbnail
        );
    }
}

А также важно! Сам поиск также переехал в LayoutBuilder

Header::make([
    Search::make(),
]),

Подробности в PR

Sortable callback

Теперь, указывая что поле sortable, вы также сможете через функцию кастомизировать сортировку:

BelongsTo::make(...)->sortable(function (Builder $query, string $column, string $direction) {
    $query->orderBy($column, $direction);
})

Или просто указать другое поле в таблице через строку:

BelongsTo::make('Author')->sortable('author_id')

Подробности в PR

Async response метод

Если требуется сделать асинхронный запрос на внешний api, где вы не контроллируете ответ, и не можете его подстроить под структуру MoonShine, то вам необходимо указать функцию обработки ответа и добавить ее в js:

ActionButton::make('Test async form', '/endpoint')->async(callback: 'myFunction')
window.myFunction = function(response, element, events, component)
{
    if(response.confirmed === true) {
        component.$dispatch('toast', {type: 'success', text: 'Success'})
    } else {
        component.$dispatch('toast', {type: 'error', text: 'Error'})
    }
}

Подробности в PR

Подробности в PR

Modal и Offcanvas компоненты

В предыдущих версиях MoonShine для вызова модального окна либо offcanvas необходимо было использовать ActionButton. Просто открыть эти компоненты без кнопки возможности не было, только если делать собственную реализацию в blade.

В релизе MoonShine v.2.4 данная проблема решена и необходимые компоненты добавлены в коробку, а также js события для открытия/закрытия компонентов:

Modal::make(
    'Confirm',
    static fn() => FormBuilder::make(route('password.confirm'))
        ->async()
        ->fields([
            Password::make('Password')->eye(),
        ])
        ->submit('Confirm'),
)->name('my-modal')->open(),


ActionButton::make(
    'Show modal',
    '/endpoint'
)->async(events: ['modal-toggled-my-modal']),
this.$dispatch('modal-toggled-my-modal')

Также пример с Offcanvas:

OffCanvasComponent::make(
    'Confirm',
    static fn() => FormBuilder::make(route('password.confirm'))
        ->async()
        ->fields([
            Password::make('Password')->eye(),
        ])
        ->submit('Confirm'),
)->name('my-canvas')->open(false)->left(),


ActionButton::make(
    'Show canvas',
    '/endpoint'
)->async(events: ['offcanvas-toggled-my-canvas']),
this.$dispatch('modal-toggled-my-modal')

Подробности в PR

Подробности в PR

Auth pipelines

Мы добавили в конфиг возможность добавлять логику в процесс аутентификации, что в процессе позволит изменить объект запроса или ответа:

return [
  'auth' => [
    'pipelines' => [
      PipelineClass::class
    ],
  ]
];

// Middleware pattern

return [
  'auth' => [
    'pipelines' => [
      new class {
        public function handle($request, $next) {
          return $next($request);
        }
      }
    ],
  ]
];

Подробности в PR

Исправлены баги 🐞

https://github.com/moonshine-software/moonshine/compare/2.3.0...2.4.0