dynamic table

This commit is contained in:
root
2026-01-10 19:43:04 +03:00
parent 5f5a28e292
commit d27f66953c
9 changed files with 387 additions and 251 deletions
+42 -43
View File
@@ -8,7 +8,7 @@ use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
use App\Models\OrganizationModel;
/**
/**
* BaseController provides a convenient place for loading components
* and performing functions that are needed by all your controllers.
*
@@ -78,8 +78,6 @@ abstract class BaseController extends Controller
'sortable' => [],
'defaultSort' => 'id',
'order' => 'asc',
'viewPath' => '',
'partialPath' => '',
'itemsKey' => 'items',
'scope' => null, // callable($builder) для дополнительных модификаций
];
@@ -159,7 +157,7 @@ abstract class BaseController extends Controller
// Получаем данные с пагинацией
$builder->select('*');
$items = $builder->limit($perPage, ($page - 1) * $perPage)->get()->getResult();
$items = $builder->limit($perPage, ($page - 1) * $perPage)->get()->getResultArray();
$from = ($page - 1) * $perPage + 1;
$to = min($page * $perPage, $total);
@@ -173,61 +171,62 @@ abstract class BaseController extends Controller
'to' => $to,
];
$pagerStub = new class($pagerData) {
private $data;
public function __construct(array $data)
{
$this->data = $data;
}
public function getCurrentPage(): int
{
return $this->data['currentPage'] ?? 1;
}
public function getPageCount(): int
{
return $this->data['pageCount'] ?? 1;
}
public function getTotal(): int
{
return $this->data['total'] ?? 0;
}
public function getDetails(): array
{
return $this->data;
}
};
$data = [
$config['itemsKey'] => $items,
'pager' => $pagerStub,
'items' => $items, // Алиас для универсального шаблона
'pagerDetails' => $pagerData,
'perPage' => $perPage,
'sort' => $sort,
'order' => $order,
'filters' => $filters,
'columns' => $config['columns'],
'actionsConfig' => $config['actionsConfig'] ?? [],
];
// В конце prepareTableData, перед return
log_message('debug', 'Total records calculated: ' . $total);
log_message('debug', 'Organization ID: ' . session()->get('active_org_id'));
log_message('debug', 'SQL Query: ' . $countBuilder->getCompiledSelect());
return $data;
}
/**
* Рендерит HTML таблицы из конфигурации
*
* @param array|null $config Конфигурация таблицы (если null, используется getTableConfig())
* @param bool $isPartial Если true, возвращает только tbody + tfoot (для AJAX)
* @return string HTML таблицы
*/
protected function renderTable(?array $config = null, bool $isPartial = false): string
{
$config = $config ?? $this->getTableConfig();
$tableData = $this->prepareTableData($config);
// Дополнительные параметры для компонента таблицы
$tableData['id'] = $config['id'] ?? 'data-table';
$tableData['url'] = $config['url'] ?? '/table';
$tableData['perPage'] = $tableData['perPage'] ?? 10;
$tableData['sort'] = $tableData['sort'] ?? '';
$tableData['order'] = $tableData['order'] ?? 'asc';
$tableData['filters'] = $tableData['filters'] ?? [];
$tableData['actions'] = $config['actions'] ?? false;
$tableData['actionsConfig'] = $config['actionsConfig'] ?? [];
$tableData['columns'] = $config['columns'] ?? [];
// Параметры для пустого состояния
$tableData['emptyMessage'] = $config['emptyMessage'] ?? 'Нет данных';
$tableData['emptyIcon'] = $config['emptyIcon'] ?? '';
$tableData['emptyActionUrl'] = $config['emptyActionUrl'] ?? '';
$tableData['emptyActionLabel'] = $config['emptyActionLabel'] ?? 'Добавить';
$tableData['emptyActionIcon'] = $config['emptyActionIcon'] ?? '';
$template = $isPartial ? '@components/table/ajax_table' : '@components/table/table';
return $this->renderTwig($template, $tableData);
}
/**
* AJAX endpoint для таблицы - возвращает partial (tbody + tfoot)
* Если запрос не AJAX - возвращает полную таблицу
*/
public function table()
{
$config = $this->getTableConfig();
$data = $this->prepareTableData($config);
if (!$this->isAjax()) {
return redirect()->to('/');
}
return $this->renderTwig($config['partialPath'], $data);
$isPartial = $this->request->getGet('format') === 'partial' || $this->isAjax();
return $this->renderTable(null, $isPartial);
}
}