На этой неделе команда MoonShine выпустила релиз v2.3.0 с кодовым именем "Bloody Boyarskiy"! Давайте взглянем на самое интересное в этом обновлении!
Возможность указать поддомен
Сделать это можно через конфиг moonshine route.domain или MOONSHINE_URL=admin.example.com
ActionButton в режиме async
Казалось, что ActionButton уже ничем не сможет удивить, но мы упустили очень важную деталь, а сейчас исправили эту оплошность!
Теперь вы можете указать метод async и запрос просто уйдет на указанный url, где вы сможете, например, отправить чек на почту:
ActionButton::make(
'Click me',
'/endpoint'
)->async()
Если Вам необходимо после клика отобразить уведомление или сделать редирект, то достаточно реализовать json ответ по структуре:
{message: 'Toast', type: 'success', redirect: '/url'}
, гдеredirect
не обязательный параметр.
Также есть возможность менять тип запроса:
ActionButton::make(
'Click me',
'/endpoint'
)->async(method: 'POST')
Если требуется по клику заменить область с html, то вы можете в ответе вернуть HTML-контент или json с ключом html {html: 'Html content'}
.
Главное, не забудьте указать selector элемента в DOM:
ActionButton::make(
'Click me',
'/endpoint'
)->async(selector: '#my-selector')
А также (это важно!), можно дернуть события после успешно выполненного запроса:
ActionButton::make(
'Click me',
'/endpoint'
)->async(events: ['table-updated-index-table'])
ColorManager
Теперь менять цвета в MoonShine стало намного удобнее. Для этого мы добавили менеджер цветов и много сахара:
public function boot(): void
{
parent::boot();
moonshineColors()
->background('#A3C3D9')
->content('#A3C3D9')
->tableRow('#AE76A6')
->dividers('#AE76A6')
->borders('#AE76A6')
->buttons('#AE76A6')
->primary('#CCD6EB')
->secondary('#AE76A6')
;
}
Как видно из примера, мы также добавили методы которые меняют цвета по областям - так проще понять, какой ключ за что отвечает.
Еще добавили магию, и вы можете изменить ключ массива цветов через магический метод. Например, если вам требуется изменить цвет success-bg
в темной теме, то кодбудет выглядеть следующим образом
moonshineColors()->successBg('#00000', dark: true);
FormBuilder apply
Если вы используете свой FormBuilder с большим набором полей и хотите в контроллере сохранить данные, но затруднятесь как вызвать apply
для каждого поля, то в таком случае вам придется по вкусу встроенный apply-метод в билдер, который самостоятельно пройдет по всем полям формы и дернет их apply-методы:
$form->apply(fn(Model $item) => $item->save());
Давайте взглянем также на сложный вариант, где мы также указываем события до сохранения и после:
$form->apply(
static fn(Model $item) => $item->save(),
before: function (Model $item) {
if (! $item->exists) {
$item = $this->beforeCreating($item);
}
if ($item->exists) {
$item = $this->beforeUpdating($item);
}
return $item;
},
after: function (Model $item) {
$wasRecentlyCreated = $item->wasRecentlyCreated;
$item->save();
if ($wasRecentlyCreated) {
$item = $this->afterCreated($item);
}
if (! $wasRecentlyCreated) {
$item = $this->afterUpdated($item);
}
return $item;
},
throw: true
);
Menu and theme closure
Объявлять меню и настраивать тему теперь можно через замыкания на основе текущего запроса. Будет полезно если вы решили использовать multi tenancy или же у вас и веб и админ часть реализована на MoonShine:
protected function menu(): Closure
{
return static function (MoonShineRequest $request) {
return [
];
};
}
protected function theme(): Closure
{
return static function (MoonShineRequest $request) {
return [];
}
}
Assets template
Теперь вы можете создавать собственные билды стилей или скриптов с использованием Vite и подклчючать их к MoonShine. При этом у вас уже будет шаблон конфига, чтобы характеристики темы не отличались.
php artisan moonshine:publish -> Assets template
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
public function boot(): void
{
parent::boot();
moonshineAssets()->add([
Vite::asset('resources/css/app.css'),
Vite::asset('resources/js/app.js'),
]);
}
}