# Development of a dashboard widget ← [To the overview of UI contributions](contributions.md) The widget consists of a description in `module.php`, a data provider (`provider`), Twig template and module styles. It automatically disappears when the module is turned off or lack of right. ## 1. Description in `module.php` ```php use App\Adminx\Notes\DashboardWidget; 'admin_extension' => array( 'icon' => 'ti ti-notes', 'dashboard' => array( 'code' => 'recent', 'label' => 'Мои заметки', 'description' => 'Последние и закреплённые заметки пользователя.', 'icon' => 'ti ti-notes', 'template' => '@notes/dashboard.twig', 'provider' => array(DashboardWidget::class, 'data'), 'permission' => 'view_notes', 'sort_order' => 24, ), ), ``` `code` generates a stable layout code `module.notes.dashboard.recent`. Don't change it after release: order settings and visibility is stored at this value. If code is not specified, the system uses ordinal number of the contribution, which is less stable when adding new widgets. `label`, `description` and `icon` are shown in the interface settings. They don't replace the header inside Twig. ## 2. Provider ```php Model::recent($userId, 6), 'summary' => Model::summary($userId), 'can_manage' => Permission::check('manage_notes'), ); } } ``` Provider is called when building a dashboard and receives no arguments. Return View data only, not HTML. Limit the selection, choose the ones you need columns and avoid separate SQL for each element. `permission` in the description already protects the contribution itself. Additional check `manage_*` in provider is needed for change buttons inside the widget. ## 3. Twig The template gets: - `module_data` — provider array; - `module_widget` - normalized description with module/layout code, label, icon and sort order; - general panel variables: `ADMINX_BASE`, `csrf_token`, user and assets. ```twig
Заметки

Последние заметки

{{ module_data.summary.total|default(0) }} всего

{% for item in module_data.items|default([]) %} {{ item.title }} {% else %}
Заметок пока нет
{% endfor %}
``` The widget must have an empty state and work correctly without optional keys provider. ## 4. Grid size The dashboard uses 12 columns. Regular `.dashboard-section` takes 4/12 on wide screen, 6/12 on medium and full width on mobile. For standard widget `6/12` use the generic class `dashboard-half`: ```twig
...
``` On mobile it will automatically take up the entire width. For a complete row, set `grid-column: 1 / -1` in the LESS module. Do not add the name of the new module to global `dashboard.less`: general dimensions are specified by primitives, special dimensions remain in the module. ## 5. Order and shutdown `sort_order` specifies only the initial position. After custom settings, the saved order from **Basic settings → Interface** is valid. On the module page, the **Place in interface** action allows you to fully disable its dashboard contribution. The description can contain a list of several widgets. Ask everyone unique `code`, `label`, `template` and suitable rights. ## Check - a role without `permission` does not see the widget and provider is not executed; - empty data shows a neat state; - order and visibility are preserved after reboot; - turning off the module removes the widget; - desktop/tablet/mobile do not allow horizontal scrolling; - links, forms and Ajax re-check eligibility on the server.