Перейти к содержимому

Групповые действия и выгрузка в своём списке админки

Доводим свой список в административной части до привычного вида: галочки, групповые действия, страницы и выгрузка для тех, кто работает с ним каждый день.

Решение

Объявляем групповые действия:

$list->AddGroupActionTable([
'delete' => 'Удалить',
'resend' => 'Отправить повторно',
'activate' => 'Включить',
]);
// галочки и кнопка «применить» появляются сами, вёрстка не нужна

Список действий описывают одной строкой кода. Галочки в строках, выбор «все на странице» и кнопка применения приходят вместе с ним, и сотрудник получает привычное поведение без вашей вёрстки.

Обрабатываем выбранные строки:

if ($ids = $list->GroupAction()) {
foreach ($ids as $id) {
if (!$USER->CanDoOperation('vendor_sync_edit')) { continue; } // права на каждой строке
SyncTable::update((int)$id, ['STATUS' => 'new']);
}
$list->ActionRedirect(); // возвращаем сотрудника на список с фильтром
}

Выбранные строки приходят массивом номеров, а не готовым запросом. Права проверяют на каждой строке отдельно: выбор «все» может задеть записи, к которым у сотрудника доступа нет.

Разбиваем список на страницы:

$res = SyncTable::getList(['filter' => $filter, 'order' => ['ID' => 'DESC']]);
$rsData = new CAdminUiResult($res, $tableId);
$rsData->NavStart();
$list->NavText($rsData->GetNavPrint('Записи'));

Список без постраничности умирает на тысяче строк. Выборка целиком в память, тысяча строк разметки и полминуты ожидания - и сотрудник перестаёт открывать эту страницу вовсе.

Добавляем выгрузку в меню списка:

$list->AddAdminContextMenu([
['TEXT' => 'Выгрузить в CSV', 'LINK' => 'vendor_sync_export.php?' . $filterQuery,
'ICON' => 'btn_excel'],
]);
// выгрузка учитывает текущий фильтр: иначе она отдаёт совсем не то, что на экране

Выгрузка живёт в меню списка, а не среди групповых действий. Она относится ко всей выборке с текущим фильтром, а не к отмеченным строкам, и путать эти две вещи сотруднику неудобно.

Долгие групповые действия не выполняют прямо в запросе. Тысяча выбранных строк с обращением к внешнему сервису на каждой - это отвалившаяся страница и половина обработанных записей.

Результат действия стоит показывать словами. Молчаливый возврат к списку оставляет сотрудника в сомнении, сработало ли вообще, и он нажимает ещё раз.

Опасные действия отделяют от обычных подтверждением. Удаление в одном списке с включением однажды срабатывает не на тех строках, и восстанавливать их будет некому.

Типичные проблемы

Групповое действие ничего не делает.

Массив выбранных строк не читается или читается не тем вызовом. Номера приходят именно из него, а не из запроса напрямую.

Действие задело чужие записи.

Права проверяются один раз, а не на каждой выбранной строке. Выбор «все» захватывает и те записи, которые именно этому сотруднику вовсе недоступны.

Страница списка открывается полминуты.

Выборка идёт целиком, без всякой постраничности и без ограничения общего числа строк. Разбивку на страницы добавляют сразу, а не когда записей станет много.

Выгрузка отдаёт не то, что видно на экране.

Она не учитывает текущий фильтр списка и отдаёт вообще все имеющиеся записи. Фильтр передают в выгрузку тем же набором параметров.

После группового действия половина строк не обработана.

Долгая операция выполняется прямо в запросе и обрывается по времени. Такие долгие действия ставят в очередь и обрабатывают их дальше по расписанию.

Частые вопросы

Можно ли сделать своё действие с вопросом?

Да, подтверждение показывают средствами ядра UI перед отправкой. Для удаления это стоит делать всегда.

Как сохранить фильтр между заходами?

Он сохраняется сам по идентификатору списка. Меняющийся идентификатор ломает это поведение.

Куда девать долгие операции?

В очередь с обработкой по расписанию и показом хода. В запросе они не помещаются.

Нужна ли выгрузка, если есть фильтр?

Обычно да: в таблице считают и сверяют, а не только смотрят. Это первая просьба после запуска списка.

Смежное

Первоисточник