105 lines
5.2 KiB
Twig
105 lines
5.2 KiB
Twig
{#
|
||
table.twig - Универсальный компонент таблицы с AJAX-загрузкой
|
||
|
||
Параметры:
|
||
- id: ID контейнера таблицы (обязательно)
|
||
- url: URL для AJAX-загрузки данных (обязательно)
|
||
- perPage: Количество записей на странице (по умолчанию 10)
|
||
- columns: Ассоциативный массив ['name' => ['label' => 'Name', 'width' => '40%']]
|
||
- sort: Текущий столбец сортировки
|
||
- order: Направление сортировки
|
||
- filters: Текущие значения фильтров
|
||
- items: Массив объектов модели (автоматический рендеринг)
|
||
- rows: Предварительно построенные строки (устаревший формат, для совместимости)
|
||
- emptyMessage: Сообщение при отсутствии данных
|
||
- emptyActionUrl: URL для кнопки действия (опционально)
|
||
- emptyActionLabel: Текст кнопки действия (опционально)
|
||
- emptyIcon: FontAwesome иконка (опционально)
|
||
- tableClass: Дополнительные классы для таблицы
|
||
#}
|
||
{% set hasRows = (rows is defined and rows|length > 0) or (items is defined and items|length > 0) %}
|
||
|
||
<div id="{{ id }}" class="data-table" data-url="{{ url }}" data-per-page="{{ perPage|default(10) }}">
|
||
<table class="table table-hover mb-0 {{ tableClass|default('') }}">
|
||
{# Заголовок таблицы #}
|
||
{{ include('@components/table/table_header.twig', {
|
||
columns: columns,
|
||
sort: sort|default(''),
|
||
order: order|default('asc'),
|
||
filters: filters|default({}),
|
||
actions: actions|default(false)
|
||
}) }}
|
||
|
||
{# Тело таблицы #}
|
||
<tbody>
|
||
{% if hasRows %}
|
||
{% if rows is defined and rows|length > 0 %}
|
||
{# Старый формат: предварительно построенные строки #}
|
||
{% for row in rows %}
|
||
<tr>
|
||
{% for cell in row.cells %}
|
||
<td class="{{ cell.class|default('') }}">{{ cell.content|raw }}</td>
|
||
{% endfor %}
|
||
{% if row.actions is defined %}
|
||
<td class="actions-cell text-end">
|
||
{{ row.actions|raw }}
|
||
</td>
|
||
{% endif %}
|
||
</tr>
|
||
{% endfor %}
|
||
{% elseif items is defined and items|length > 0 %}
|
||
{# Новый формат: автоматический рендеринг из объектов модели #}
|
||
{% set columnKeys = columns|keys %}
|
||
{% for item in items %}
|
||
<tr>
|
||
{# Ячейки данных #}
|
||
{% for columnKey in columnKeys %}
|
||
<td>{{ attribute(item, columnKey)|default('—') }}</td>
|
||
{% endfor %}
|
||
|
||
{# Колонка действий #}
|
||
{% if actions is defined and actions %}
|
||
<td class="actions-cell text-end">
|
||
{% if item.actions is defined %}{{ item.actions|raw }}{% endif %}
|
||
</td>
|
||
{% endif %}
|
||
</tr>
|
||
{% endfor %}
|
||
{% endif %}
|
||
{% else %}
|
||
{# Пустое состояние #}
|
||
<tr>
|
||
<td colspan="{{ columns|length + (actions is defined and actions ? 1 : 0) }}"
|
||
class="text-center py-5">
|
||
{% if emptyIcon is defined and emptyIcon %}
|
||
<div class="mb-3">
|
||
<i class="{{ emptyIcon }} text-muted" style="font-size: 3rem;"></i>
|
||
</div>
|
||
{% endif %}
|
||
<p class="text-muted mb-3">{{ emptyMessage|default('Нет данных для отображения') }}</p>
|
||
{% if emptyActionUrl is defined and emptyActionUrl %}
|
||
<a href="{{ emptyActionUrl }}" class="btn btn-primary">
|
||
{% if emptyActionIcon is defined and emptyActionIcon %}
|
||
<i class="{{ emptyActionIcon }} me-2"></i>
|
||
{% endif %}
|
||
{{ emptyActionLabel|default('Добавить') }}
|
||
</a>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% endif %}
|
||
</tbody>
|
||
|
||
<tfoot>
|
||
<tr>
|
||
<td colspan="{{ columns|length + 1 }}">
|
||
{{ include('@components/table/pagination.twig', {
|
||
pagination: pagerDetails,
|
||
id: id
|
||
}) }}
|
||
</td>
|
||
</tr>
|
||
</tfoot>
|
||
</table>
|
||
</div>
|