larikmc / yii2-admin
Unified admin module for Yii2 backend with dashboard, auth and RBAC
Requires
- php: >=8.1
- yiisoft/yii2: ~2.0
- yiisoft/yii2-bootstrap5: ~2.0
This package is auto-updated.
Last update: 2026-05-07 08:35:03 UTC
README
Готовое расширение для Yii2 backend: одна установка, один модуль admin, внутри уже есть:
- dashboard и общий layout админки
- авторизация и страница входа
- восстановление пароля для админки
- RBAC: роли, действия и назначения
- одноразовые инвайты для регистрации администратора
- security log
- очистка кеша
- системный bootstrap для
admin,adminPanelи защитных инвариантов root-пользователяID=1
Пакет рассчитан на сценарий, где админка, auth и RBAC живут вместе как единая backend-платформа.
Перед интеграцией UI обязательно прочитайте раздел UI guide в этом README.
Связанные документы:
AI-INTEGRATION-CHECKLIST.md(обязательный чеклист для нейросети при интеграции в новый проект)
Требования
- PHP 8.1+
- Yii2 2.0.x
yiisoft/yii2-bootstrap5authManager=yii\rbac\DbManager
Что дает пакет
После подключения у вас есть:
/admin/admin/login/admin/auth/request-password-reset/admin/auth/reset-password?token=.../admin/auth/invite?token=.../admin/site/ui-kit/admin/auth/security-log/admin/rbac/admin/rbac/user/admin/rbac/role/admin/rbac/permission/admin/rbac/assignment/admin/rbac/invite
Внутри RBAC уже поддержана схема:
действия -> роли -> пользователи
То есть:
- создаете действия
- включаете действия в роль
- назначаете роль пользователю
Установка
Composer
composer require larikmc/yii2-admin
После обновления пакета
После composer update (или после переключения версии/тега) рекомендуется:
- очистить опубликованные ассеты Yii (
web/assets/*) - очистить кеш приложения (
php yii cache/flush-all, если команда доступна) - сделать hard refresh в браузере (
Ctrl+F5)
Это нужно, чтобы сразу подтянулись обновленные css/js и новые view-шаблоны расширения.
Для локального path-пакета:
{
"repositories": [
{
"type": "path",
"url": "../yii2-admin",
"options": {
"symlink": true,
"relative": true
}
}
],
"require": {
"larikmc/yii2-admin": "@dev"
}
}
Базовая конфигурация backend
Пример для backend/config/main.php:
'defaultRoute' => 'admin/site/index', 'layout' => '@larikmc/admin/views/layouts/main', 'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, 'userClass' => common\models\User::class, 'userModel' => common\models\User::class, 'userIdField' => 'id', 'usernameField' => 'username', 'emailField' => 'email', 'statusField' => 'status', 'rbacAccessRoles' => [], // Настройки авторизации 'maxUserAttempts' => 5, 'captchaAfterAttempts' => 3, 'lockDuration' => 120, 'userAttemptsTtl' => 120, 'maxDelaySeconds' => 10, // Необязательно: свой placeholder для lazyload. // Если не задано, используется стандартный src/web/img/load.svg из расширения. 'lazyloadPlaceholderUrl' => null, ], ], 'components' => [ 'request' => [ 'baseUrl' => '/admin', ], 'user' => [ 'identityClass' => common\models\User::class, 'enableAutoLogin' => true, 'loginUrl' => ['/login'], ], 'authManager' => [ 'class' => yii\rbac\DbManager::class, ], 'urlManager' => [ 'enablePrettyUrl' => true, 'showScriptName' => false, 'rules' => [ '' => 'admin/site/index', 'admin/error' => 'admin/site/error', 'login' => 'admin/auth/auth/login', 'auth/login' => 'admin/auth/auth/login', 'auth/logout' => 'admin/auth/auth/logout', 'auth/captcha' => 'admin/auth/auth/captcha', 'auth/invite' => 'admin/auth/auth/invite', 'auth/request-password-reset' => 'admin/auth/auth/request-password-reset', 'auth/reset-password' => 'admin/auth/auth/reset-password', 'auth/security-log' => 'admin/auth/auth/security-log', 'auth/clear-security-log' => 'admin/auth/auth/clear-security-log', 'rbac' => 'admin/rbac/default/index', 'rbac/<controller:[\w-]+>' => 'admin/rbac/<controller>/index', 'rbac/<controller:[\w-]+>/<action:[\w-]+>' => 'admin/rbac/<controller>/<action>', 'rbac/<controller:[\w-]+>/<action:[\w-]+>/<id:\d+>' => 'admin/rbac/<controller>/<action>', 'rbac/<controller:[\w-]+>/<action:[\w-]+>/<name:[\w-]+>' => 'admin/rbac/<controller>/<action>', ], ], 'errorHandler' => [ // Обязательно: чтобы 403/404/500 внутри админки рендерились шаблоном расширения. 'errorAction' => '/admin/site/error', ], ],
Примечание по rules: порядок важен. Сохраняйте этот блок целиком, а project-specific правила добавляйте так, чтобы не ломать маршруты auth/* и rbac/*.
Error page (обязательно)
Чтобы использовался шаблон ошибки из расширения (@larikmc/admin/views/site/error.php), в приложении должен быть задан:
'components' => [ 'errorHandler' => [ 'errorAction' => '/admin/site/error', ], ],
Без этого Yii может показывать стандартную страницу ошибки вместо оформленной страницы админки.
Важные пути для входа (рекомендуемый вариант)
Чтобы страница входа открывалась по короткому URL:
https://your-domain/admin/login
используйте такую связку:
request.baseUrl = '/admin'user.loginUrl = ['/login']- правило
urlManager:'login' => 'admin/auth/auth/login' - правило
urlManager:'auth/captcha' => 'admin/auth/auth/captcha'
Если у вас есть глобальная проверка доступа в on beforeRequest, обязательно добавьте в whitelist:
loginauth/loginauth/captchaauth/request-password-resetauth/reset-passwordauth/inviteadmin/loginadmin/auth/loginadmin/auth/captchaadmin/auth/request-password-resetadmin/auth/reset-passwordadmin/auth/invite
Иначе можно получить цикл редиректов (ERR_TOO_MANY_REDIRECTS) на странице входа.
Схема доступа
Рекомендуемая схема разделения доступа:
adminPanelдает право войти в админкуadminдает доступ к рабочим backend-контроллерам и административным разделам
То есть:
- пользователь без
adminPanelне должен попадать в/admin - пользователь с
adminPanel, но безadmin, может пройти только уровень входа в админку - backend-контроллеры, dashboard, RBAC и security log должны быть закрыты ролью
admin
Security Model
Матрица доступа по умолчанию:
adminPanel— право пройти в/adminadmin— право работать с backend-контроллерамиadmin— право видеть dashboard и внутренние admin-страницыadmin— право работать с RBACadmin— право просматривать и очищать security log
Коротко:
adminPanel= вход в админкуadmin= вся рабочая часть админки
Меню
Основное меню и нижнее меню задаются через:
menusecondaryMenu
По умолчанию пакет использует схему, совпадающую с текущим UI:
menu: dashboard + dropdownАдминистрированиесRBAC,Инвайт администратораиSecurity LogsecondaryMenu: толькоADMIN-UI-KIT
Важно:
- ссылки
На сайт,Очистить кеш,Выйтине должны дублироваться вsecondaryMenu - эти действия уже встроены в topbar layout и находятся справа в шапке
- если добавить их ещё и в
secondaryMenu, получится старый дублирующийся sidebar-паттерн, который больше не является эталонным для пакета
Пример:
'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, 'userClass' => common\models\User::class, 'userModel' => common\models\User::class, 'menu' => [ [ 'icon' => 'dashboard', 'label' => 'Панель управления', 'url' => ['/admin/site/index'], ], [ 'icon' => 'admin_panel_settings', 'label' => 'Администрирование', 'items' => [ ['label' => 'RBAC', 'url' => ['/rbac/default/index']], ['label' => 'Инвайт администратора', 'url' => ['/rbac/invite/index']], ['label' => 'Security Log', 'url' => ['/auth/security-log']], ], ], ], 'secondaryMenu' => [ [ 'icon' => 'palette', 'label' => 'ADMIN-UI-KIT', 'url' => ['/admin/site/ui-kit'], ], ], ], ],
Авторизация
В пакет уже встроен модуль авторизации:
- форма входа
- встроенное восстановление пароля для админки
- brute-force защита
- CAPTCHA после нескольких попыток
- lock по IP и email
- security log
- регистрация администратора по одноразовой ссылке
Маршруты:
GET/POST /admin/auth/loginGET/POST /admin/auth/request-password-resetGET/POST /admin/auth/reset-password?token=...GET/POST /admin/auth/invite?token=...POST /admin/auth/logoutGET /admin/auth/captchaGET /admin/auth/security-logPOST /admin/auth/clear-security-log
Внутри пакета используются короткие маршруты /auth/*, поэтому их нужно пробросить через urlManager.
Восстановление пароля
В странице входа уже встроена ссылка Забыли пароль?.
Сценарий работы:
- пользователь открывает
/admin/auth/request-password-reset - вводит email
- интерфейс всегда показывает одинаковое нейтральное success-состояние
- письмо реально отправляется только если пользователь существует, имеет доступ
adminPanel, модель поддерживает reset-token и в приложении настроенmailer
Это сделано специально, чтобы не раскрывать, какие email существуют в админке.
После успешной отправки форма скрывается, а на странице остается только сообщение и ссылка возврата ко входу.
Инвайт администратора
В пакет встроен сценарий регистрации нового администратора по одноразовой ссылке.
Сценарий работы:
- администратор открывает
/admin/rbac/invite - генерирует ссылку приглашения
- ссылка автоматически копируется в буфер обмена
- приглашенный пользователь открывает
/admin/auth/invite?token=... - проходит регистрацию
- после регистрации автоматически получает роль
adminи попадает в админку
Ограничения:
- генерация invite-ссылки доступна пользователям с ролью
admin - invite одноразовый
- системные ограничения для
ID=1относятся к защите root-администратора (рольadminне снимается), а не к генерации invite
Совместимость с моделью пользователя:
- если в проекте нет колонки
username, задайтеusernameField = 'email' - invite-регистрация автоматически подстроится и не будет выполнять SQL по
username - если
usernameесть как отдельное поле, форма invite продолжает работать в классическом режиме (логин + email + пароль)
RBAC
В пакет уже встроен RBAC-раздел:
- роли
- действия
- назначения ролей пользователям
- генерация одноразовых invite-ссылок для новых администраторов
Маршруты:
/admin/rbac/admin/rbac/user/admin/rbac/role/admin/rbac/permission/admin/rbac/assignment/admin/rbac/invite
Системные элементы
При установке RBAC автоматически создаются:
- роль
admin - действие
adminPanel - связь
admin -> adminPanel - назначение роли
adminпользователюID=1
Системные инварианты:
- пользователь с
ID=1является системным администратором и не может быть лишен ролиadmin - роль
adminявляется системной и не может быть удалена - действие
adminPanelявляется системным и не может быть удалено - связь
admin -> adminPanelдолжна существовать всегда - у пользователя с
ID=1рольadminдолжна сохраняться всегда - генерация invite-ссылок доступна пользователям с ролью
admin
Связь системных прав:
adminPanelсчитается системным permission для входа в админку- роль
adminдолжна включатьadminPanel - назначение только
adminPanelбез ролиadminможно использовать как технический допуск на уровень входа, но не как доступ к backend-разделам
Troubleshooting
Показывается дефолтная страница ошибки Yii вместо админской
Проверьте, что в конфиге приложения задано:
'errorHandler' => [ 'errorAction' => '/admin/site/error', ],
Также проверьте rule:
'admin/error' => 'admin/site/error',
Пропали стили в админке или отображается "голый" UI
Обычно это кеш опубликованных ассетов. Выполните:
- очистку
web/assets/* - очистку кеша приложения
Ctrl+F5в браузере
Циклический редирект на странице логина
Проверьте связку:
request.baseUrl = '/admin'user.loginUrl = ['/login']- правило
'login' => 'admin/auth/auth/login' - whitelist маршрутов входа/капчи/reset/invite в
beforeRequest-guard
403 на /admin/rbac/invite
Генерация инвайтов доступна роли admin. Проверьте, что у пользователя назначена роль admin в RBAC.
Общий контейнер страниц
В пакет встроен виджет:
larikmc\admin\widgets\AdminPage
Он нужен для единообразных внутренних страниц модулей. Его можно использовать и в собственных admin-разделах.
Пример:
echo \larikmc\admin\widgets\AdminPage::widget([ 'title' => 'Моя страница', 'subtitle' => 'Короткое описание раздела', 'actions' => [ \yii\bootstrap5\Html::a('Создать', ['create'], ['class' => 'btn btn-success']), ], 'content' => '<div>Контент страницы</div>', ]);
sz-panel
Базовый визуальный контейнер админки:
.sz-panel
Он задает:
- белый фон
- внутренние отступы
- скругление
- тень карточки
Используйте его для списков, форм, таблиц и detail-экранов, если нужен единый стиль панели.
Важно: не генерируйте для этого расширения лишнюю разметку (включая собственные breadcrumbs, дополнительные обертки под стили и отдельные UI-каркасы), если используете штатный layout админки. Виджет AdminPage, меню и базовые стили уже встроены и подключаются самим пакетом.
Пример ручного использования:
<div class="sz-panel">
<?= \yii\grid\GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => $columns,
]) ?>
</div>
Или для формы:
<div class="sz-panel">
<?= $this->render('_form', ['model' => $model]) ?>
</div>
Если страница строится через AdminPage, панель можно получить автоматически:
echo \larikmc\admin\widgets\AdminPage::widget([ 'title' => 'Список товаров', 'content' => \yii\grid\GridView::widget([...]), ]);
По умолчанию AdminPage оборачивает контент в .sz-panel.
Если панель нужна вручную в самом шаблоне, отключите автообертку:
echo \larikmc\admin\widgets\AdminPage::widget([ 'title' => 'Журнал безопасности', 'boxed' => false, 'content' => '<div class="sz-panel">...</div>', ]);
Плоский вариант без карточки:
.sz-panel--flat
Важно:
sz-panelэто базовый surface-контейнер для внутренних блоков админки- таблицы, формы, detail-view и типовые контентные секции должны жить внутри
sz-panel, если не нужен осознанно плоский вариант - для ручных alert-блоков не нужно возвращаться к bootstrap-default рамкам и фонам, если экран уже собирается из
sz-panelи toast-паттернов
Lazyload и popup для изображений
В расширение уже встроены:
- lazyload для изображений:
src/web/js/lazyloader.js - popup-просмотрщик оригинала:
src/web/js/image-viewer-admin.js - стили popup:
src/web/css/image-viewer-admin.css
Все эти файлы подключаются через larikmc\admin\assets\AppAsset, поэтому при штатном layout @larikmc/admin/views/layouts/main ничего отдельно регистрировать не нужно.
Стандартный placeholder для lazyload уже лежит в расширении:
src/web/img/load.svg
По умолчанию используется именно он. Если нужен свой placeholder, задайте его в конфиге модуля:
'modules' => [ 'admin' => [ 'class' => larikmc\admin\Module::class, 'lazyloadPlaceholderUrl' => '@web/img/load.svg', ], ],
В view URL placeholder лучше получать через модуль:
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this);
Базовый пример
Миниатюра грузится лениво из data-src, а по клику открывается оригинал из data-image-full:
use yii\bootstrap5\Html; $placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); echo Html::a( Html::img($placeholder, [ 'data-src' => '/uploads/images/thumbs/item-123.webp', 'class' => 'sz-thumb__img', 'alt' => 'Изображение #123', 'loading' => 'lazy', 'decoding' => 'async', ]), '/uploads/images/original/item-123.jpg', [ 'data-pjax' => '0', 'data-image-viewer' => true, 'data-image-full' => '/uploads/images/original/item-123.jpg', 'data-image-title' => 'Изображение #123', 'class' => 'sz-thumb', 'style' => 'width:100px;height:72px;', ] );
Что здесь важно:
img[data-src]— URL миниатюры, которую нужно показать в таблице или спискеimg[src]— placeholder, по умолчанию стандартныйload.svgиз расширенияa[data-image-full]— URL полного изображения для popupa[href]— fallback для popup и обычная ссылка, если JS не загрузилсяa.sz-thumb— готовый контейнер, который центрирует placeholder и миниатюру, но не диктует размерimg.sz-thumb__img— картинка внутри контейнера, вписывается без растягиванияdata-pjax="0"— желательно для ссылок внутриGridView/PJAX, чтобы клик не перехватывался PJAX
Размер задаётся проектом:
['class' => 'sz-thumb', 'style' => 'width:100px;height:72px;']
Или готовым модификатором для типовых случаев:
sz-thumb sz-thumb--sm— 72x56sz-thumb sz-thumb--lg— 140x96sz-thumb sz-thumb--cover— изображение заполняет контейнер черезobject-fit: cover
Если миниатюра и оригинал совпадают
Можно не указывать data-image-full: popup возьмёт URL из href.
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); echo Html::a( Html::img($placeholder, [ 'data-src' => '/uploads/images/item-123.jpg', 'class' => 'sz-thumb__img', 'alt' => 'Изображение #123', ]), '/uploads/images/item-123.jpg', [ 'data-pjax' => '0', 'data-image-viewer' => true, 'data-image-title' => 'Изображение #123', 'class' => 'sz-thumb', 'style' => 'width:100px;height:72px;', ] );
Пример для GridView
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); [ 'attribute' => 'image', 'format' => 'raw', 'value' => static function ($model) use ($placeholder) { $thumb = '/uploads/images/items/thumbs/' . $model->image . '.webp'; $original = '/uploads/images/items/original/' . $model->image . '.jpg'; return \yii\bootstrap5\Html::a( \yii\bootstrap5\Html::img($placeholder, [ 'data-src' => $thumb, 'class' => 'sz-thumb__img', 'alt' => '', 'loading' => 'lazy', 'decoding' => 'async', ]), $original, [ 'data-pjax' => '0', 'data-image-viewer' => true, 'data-image-full' => $original, 'data-image-title' => 'Изображение #' . $model->id, 'class' => 'sz-thumb', 'style' => 'width:100px;height:72px;', ] ); }, ]
Legacy-вариант с onclick
Старый backend-паттерн тоже поддерживается:
$placeholder = Yii::$app->getModule('admin')->getLazyloadPlaceholderUrl($this); echo '<a class="sz-thumb" style="width:100px;height:72px;" data-pjax="0" data-image-viewer data-image-full="/uploads/images/original/item-123.jpg" data-image-title="Изображение #123" href="/uploads/images/original/item-123.jpg" onclick="return openAdminImageViewer(this)">' . '<img class="sz-thumb__img" src="' . $placeholder . '" data-src="/uploads/images/thumbs/item-123.webp" alt="">' . '</a>';
Новый вариант без inline onclick предпочтительнее: достаточно атрибута data-image-viewer.
Поддерживаемые атрибуты
data-srcнаimg— лениво подставляется вsrcdata-srcsetнаimg— лениво подставляется вsrcsetdata-no-placeholderнаimg— не добавлять классlazy-imgdata-image-viewerна ссылке — включает popup по кликуdata-image-fullна ссылке — оригинал для popupdata-image-titleна ссылке — подпись под изображениемtitleна ссылке — fallback для подписиhrefна ссылке — fallback для оригинала
Где должен лежать placeholder
Если вы ничего не настраиваете, placeholder берётся из расширения:
src/web/img/load.svg
После публикации Yii asset'ов он будет доступен по URL опубликованного AppAsset.
Если в конкретном проекте нужен другой spinner/placeholder, положите его в web-root проекта, например:
backend/web/img/load.svg
и укажите:
'lazyloadPlaceholderUrl' => '@web/img/load.svg',
Можно указать и абсолютный URL:
'lazyloadPlaceholderUrl' => 'https://cdn.example.com/admin/load.svg',
Обновление после AJAX/PJAX
При обычной загрузке страницы lazyload стартует сам. Если контент добавлен динамически, можно переинициализировать изображения внутри контейнера:
lazyloader.init(document.querySelector('#pjax-container'));
Если используется Yii PJAX:
document.addEventListener('pjax:end', function (event) { if (window.lazyloader) { window.lazyloader.init(event.target); } });
Popup использует делегирование клика на document, поэтому для новых ссылок с data-image-viewer повторная инициализация не нужна.
UI и grouped action-кнопки
В расширение уже встроены:
- общий layout админки
- базовые UI-стили
- переопределённые bootstrap-кнопки
.btn-* - стилизованные bootstrap-badges
.badge.text-bg-* - стили таблиц
- grouped action-кнопки в
GridView - showcase-страница
ADMIN-UI-KIT
Bootstrap-кнопки
Расширение не требует заводить отдельные "новые" классы для основных кнопок.
Вместо этого переопределяются стандартные bootstrap-классы:
.btn-primary.btn-secondary.btn-success.btn-danger.btn-warning.btn-info.btn-light.btn-outline-*
Это сделано специально, чтобы существующие view на Yii2 + Bootstrap 5 автоматически подхватывали новый стиль без массового переименования классов.
Bootstrap badges
Аналогично, для статусов и коротких меток используется стандартный bootstrap-формат:
.badge.text-bg-primary.text-bg-secondary.text-bg-success.text-bg-danger.text-bg-warning.text-bg-info.text-bg-light.text-bg-dark
То есть статусы и label-метки теперь лучше строить именно через bootstrap badges, а не через отдельные кастомные status-компоненты.
ADMIN-UI-KIT
Внутри пакета есть отдельная служебная страница:
/admin/site/ui-kit
Она нужна как showcase текущего визуального языка:
- solid buttons
- outline buttons
- badges
- metric card
- grouped action-column buttons
Удобно использовать её как reference, когда нужно повторить стиль в собственных backend-разделах.
То есть такие кнопки, как view/edit/delete, уже оформлены внутри пакета и не требуют ручного копирования CSS в проект, если используется штатный layout и asset bundle расширения.
Topbar и H1
В текущем layout заголовок страницы показывается в topbar автоматически через $this->title.
Это значит:
- topbar
H1приходит не изAdminPage, а из layoutsrc/views/layouts/main.php - параметр
showHeaderвAdminPageуправляет только внутренним заголовком внутри контента страницы showHeader => falseнужен как раз для того, чтобы не дублировать один и тот же заголовок и subtitle под topbar- для RBAC, security log и типовых CRUD-экранов
showHeader => falseявляется нормальным сценарием, еслиtitleуже выведен в topbar
Важно:
- в пакете нет рабочего параметра
showTopbarTitle - попытка "чинить" отсутствие заголовка через
$this->params['showTopbarTitle'] = trueявляется неправильной, потому что layout этот параметр не использует - если topbar
H1пропал, нужно проверятьlayout,$this->title, переопределённые view и фактическую версию пакета, а не размазывать по vendor-view несуществующий флаг
Важно понимать:
- если в другом проекте grouped-кнопки "не получились", это обычно не значит, что нужно просто вручную вставить CSS из README
- чаще причина в одном из пунктов:
- не подключился asset bundle расширения
- в
ActionColumnдругойtemplate - не проставлен класс
action-column - не проставлен класс
sz-row-action - не подключены
Material Symbols
Подробная техническая шпаргалка по этим кнопкам описана в разделе UI guide ниже.
UI guide
Этот раздел описывает текущий UI-слой админки larikmc/yii2-admin.
Где находится UI
- Layout:
src/views/layouts/main.php - Базовые стили:
src/web/css/style.css - Сайдбар:
src/web/css/dashboard.css - Главная dashboard-страница:
src/views/site/index.php - Стили dashboard-страницы:
src/web/css/home.css - JS для sidebar / dropdown / toast:
src/web/js/dashboard.js - Asset bundle:
src/assets/AppAsset.php
Как устроен текущий дизайн
- Основа интерфейса: светлый glass/panel стиль на cold blue/slate палитре.
- Сайдбар: тёмный, глубокий, с мягкой подсветкой и active-state у текущего пункта.
- Верхняя шапка: compact topbar с breadcrumbs и заголовком слева, utility-кнопками и аккаунтом справа.
- Карточки: крупные радиусы, мягкие границы, лёгкие градиенты, без тяжёлых bootstrap-рамок.
- Таблицы: стандартный Yii
GridView, но actions и часть UI переоформлены вручную.
Текущие UI-правила
- Не возвращать стандартные bootstrap alert'ы. Вместо них используются toast-уведомления справа сверху.
- Не дублировать один и тот же смысл в topbar и в контенте страницы.
- Для CRUD-страниц используется схема:
- topbar: breadcrumbs + title
- ниже отдельная actions-bar с кнопками
- ниже основной контент
- Для dashboard используется тот же compact topbar, что и для внутренних разделов.
- Кнопки действий в таблицах должны оставаться grouped, иконки в одной группе, без промежутков между сегментами.
- Аккаунт справа открывает dropdown только с logout-действием.
Быстрые действия в topbar
Справа в шапке сейчас есть:
- переход на сайт
- очистка кеша
- аккаунт с dropdown
Все три элемента должны выглядеть как единый набор: одинаковая высота, близкие радиусы, одна визуальная система.
Dashboard
Главная страница строится из двух зон:
- верхний hero-инфоблок
- сетка status-карточек
Текущее правило для hero:
- заголовок приветствия находится в topbar, а не внутри hero
- внутри hero остаётся только красиво оформленная системная информация
Табличные action-кнопки
Текущая реализация:
- используются
Material Symbols - ссылки имеют класс
sz-row-action - в
ActionColumnкнопки должны быть сгруппированы визуально как единая button-group - hover без подъёма
Если править таблицы, лучше не полагаться только на .action-column a, а оставлять явный класс sz-row-action.
Что важно не сломать
appendTimestampиforceCopyуже включались в приложении, чтобы assets обновлялись корректно- layout и стили правятся в локальном пакете
d:\OpenServer6.5.0\home\yii2-admin, а не только в приложении - для CRUD-страниц часть view лежит уже в самом проекте
backend/views/... - для RBAC часть view лежит внутри пакета
src/rbac/views/...
Если нужно продолжать развитие UI
Предпочтительные направления:
- унифицировать все
GridViewфильтры и toolbar - держать одинаковую высоту topbar во всех разделах
- не добавлять лишний текст в hero и header
- сохранять холодную slate/blue палитру без слишком ярких кислотных акцентов
- новые элементы делать в том же стиле: мягкий border, glass-light background, крупный radius
Перед правками полезно проверить
src/views/layouts/main.phpsrc/web/css/style.csssrc/web/css/home.css- конкретную view проекта, если страница переопределена в
backend/views/...
После правок
- использовать жёсткое обновление страницы:
Ctrl+F5 - при сомнениях проверять опубликованные assets Yii
- для PHP view-файлов полезно гонять
php -l
Структура пакета
yii2-admin/
├─ src/
│ ├─ assets/
│ ├─ auth/
│ ├─ config/
│ ├─ controllers/
│ ├─ rbac/
│ ├─ views/
│ ├─ web/
│ ├─ widgets/
│ └─ Module.php
├─ composer.json
└─ README.md
Идея пакета
Это не набор из трех независимых расширений, а одна backend-платформа:
admin shellauthrbac
Именно поэтому пакет удобнее ставить и поддерживать как одно расширение.
Лицензия
BSD-3-Clause