diff --git a/UI_CHECKLIST.md b/UI_CHECKLIST.md index 91a6c8c..ea01b1d 100644 --- a/UI_CHECKLIST.md +++ b/UI_CHECKLIST.md @@ -129,8 +129,8 @@ - [x] Перенести raw UCI show/set/commit/revert. - [x] Перенести низкоуровневое управление пакетами. - [x] Перенести полную историю команд. -- [ ] Сократить основные фильтры истории до «Все», «Выполняются», «Ошибка». -- [ ] Перенести дополнительные фильтры в меню. +- [x] Сократить основные фильтры истории до «Все», «Выполняются», «Ошибка». +- [x] Перенести дополнительные фильтры в меню. - [x] Перенести аудит. - [x] Добавить предупреждение перед опасными действиями. - [ ] Подготовить экспертный режим к разграничению прав. diff --git a/web/app.js b/web/app.js index d383919..a031f65 100644 --- a/web/app.js +++ b/web/app.js @@ -6,6 +6,7 @@ const state = { filter: "all", clientFilter: "all", commandFilter: "all", + commandStatusFilter: "", commands: [], alerts: [], remoteSessions: [], @@ -131,6 +132,7 @@ const els = { reloadCommandsBtn: document.querySelector("#reloadCommandsBtn"), reloadAuditBtn: document.querySelector("#reloadAuditBtn"), commandSummary: document.querySelector("#commandSummary"), + commandStatusFilter: document.querySelector("#commandStatusFilter"), auditSummary: document.querySelector("#auditSummary"), commandList: document.querySelector("#commandList"), commandDetailPanel: document.querySelector("#commandDetailPanel"), @@ -236,18 +238,57 @@ function formatShortDate(value) { function statusLabel(status) { return { - requested: "Requested", - queued: "Queued", - active: "Active", - closed: "Closed", - claimed: "Running", - completed: "Done", - failed: "Failed", - cancelled: "Cancelled", - expired: "Expired", + requested: "Запрошено", + queued: "В очереди", + active: "Активно", + closed: "Закрыто", + claimed: "Выполняется", + completed: "Готово", + failed: "Ошибка", + cancelled: "Отменено", + expired: "Истекло", }[status] || status || "-"; } +function commandTypeLabel(type) { + return { + ping: "Проверка связи", + traceroute: "Маршрут до узла", + route_show: "Показ маршрутов", + interfaces_show: "Показ интерфейсов", + reboot: "Перезагрузка", + service_restart: "Перезапуск сервиса", + pkg_list_installed: "Список пакетов", + pkg_update: "Обновление индекса пакетов", + pkg_list_upgradable: "Доступные обновления пакетов", + pkg_install: "Установка пакета", + pkg_remove: "Удаление пакета", + opkg_list_installed: "Список пакетов", + opkg_update: "Обновление индекса пакетов", + opkg_list_upgradable: "Доступные обновления пакетов", + opkg_install: "Установка пакета", + opkg_remove: "Удаление пакета", + uci_show: "Просмотр UCI", + uci_backup: "Резервная копия UCI", + uci_preview: "Проверка изменения настроек", + uci_set: "Подготовка изменения настроек", + uci_commit: "Применение настроек", + uci_commit_confirmed: "Безопасное применение настроек", + uci_revert: "Отмена staged-настроек", + uci_restore: "Восстановление настроек", + remote_ssh_reverse: "Открытие удаленного доступа", + remote_ssh_close: "Закрытие удаленного доступа", + }[type] || type || "-"; +} + +function commandFilterMatches(command) { + if (state.commandStatusFilter && command.status !== state.commandStatusFilter) return false; + if (state.commandFilter === "running") return command.status === "queued" || command.status === "claimed"; + if (state.commandFilter === "failed") return ["failed", "expired", "cancelled"].includes(command.status); + if (state.commandFilter === "completed") return command.status === "completed"; + return true; +} + function remoteStatusLabel(status) { return { requested: "Запрашивается", @@ -759,33 +800,33 @@ async function loadCommands() { function renderCommands(commands) { els.commandList.innerHTML = ""; renderCommandSummary(commands); - const filtered = state.commandFilter === "all" ? commands : commands.filter((command) => command.status === state.commandFilter); + const filtered = commands.filter(commandFilterMatches); if (filtered.length === 0) { - els.commandList.textContent = "No commands"; + els.commandList.innerHTML = '
${escapeHtml(output)}