style: compact icon action buttons, no horizontal scroll

Replace text action buttons with 32px icon buttons (tooltips kept
via title/aria-label): ⏻ выключить, ▶ включить, ⬇ .conf,
🔗 прямая ссылка, ⧉ копировать URL, 🗑 удалить. Actions cell
shrinks to content (width:1%, nowrap) so the table fits without
left-right scrolling.
This commit is contained in:
andrey271192
2026-06-16 19:57:49 +03:00
parent 4ebb81cede
commit 2899bba55f
2 changed files with 34 additions and 7 deletions

View File

@@ -988,31 +988,31 @@ function renderRows(clients) {
actTd.appendChild(lock);
} else {
if (c.activeInConf) {
actTd.appendChild(btn("Выключить", "btn small ghost", () => openDisableDialog(c)));
actTd.appendChild(iconBtn("⏻", "Выключить", "btn small ghost icon", () => openDisableDialog(c)));
} else {
actTd.appendChild(
btn("Включить", "btn small primary", () => mutate("/api/clients/enable", c.clientId))
iconBtn("▶", "Включить", "btn small primary icon", () => mutate("/api/clients/enable", c.clientId))
);
}
if (c.exportAvailable) {
const direct = document.createElement("a");
direct.className = "btn small ghost";
direct.href = clientExportGetUrl(c.clientId);
direct.textContent = "Прямая ссылка";
direct.textContent = "🔗"; direct.classList.add("icon");
direct.rel = "noopener";
direct.title =
"Открыть в новой вкладке — скачается .conf, если вы авторизованы в этой панели (cookies).";
actTd.appendChild(btn("Скачать .conf", "btn small ghost", () => void downloadClientConfig(c)));
actTd.appendChild(iconBtn("⬇", "Скачать .conf", "btn small ghost icon", () => void downloadClientConfig(c)));
actTd.appendChild(direct);
actTd.appendChild(
btn("Копировать URL", "btn small ghost", async () => {
iconBtn("⧉", "Копировать URL", "btn small ghost icon", async () => {
const ok = await copyTextToClipboard(clientExportGetUrl(c.clientId));
setStatus(ok ? "Ссылка скопирована (вставьте в браузер, будучи залогиненным)." : "Не удалось скопировать.", !ok);
}),
);
}
actTd.appendChild(btn("Удалить", "btn small warn", () => confirmDelete(c.name, c.clientId)));
actTd.appendChild(iconBtn("🗑", "Удалить", "btn small warn icon", () => confirmDelete(c.name, c.clientId)));
}
tr.append(nameTd, ipTd, stTd, offTd, actTd);
@@ -1029,6 +1029,17 @@ function btn(label, cls, onClick) {
return b;
}
function iconBtn(glyph, title, cls, onClick) {
const b = document.createElement("button");
b.type = "button";
b.className = cls;
b.textContent = glyph;
b.title = title;
b.setAttribute("aria-label", title);
b.addEventListener("click", onClick);
return b;
}
/** Для политики WARP на сервере нужны IPv4 вида 10.8.x.x/32 */
function parseIpv4Cidrs(allowedIps) {
if (!allowedIps) return [];