diff --git a/VERSION b/VERSION
index ccefc02..202169a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.137
+0.0.138
diff --git a/frontend/settings.html b/frontend/settings.html
index 4cad582..d5ae907 100644
--- a/frontend/settings.html
+++ b/frontend/settings.html
@@ -47,7 +47,7 @@
- | ID | Камера | IP | Потоки | Вкл | Запись | Хранилище | Статус |
+ | ID | Камера | IP | Потоки | Вкл | Запись | Хранилище | Статус | |
diff --git a/frontend/static/app.js b/frontend/static/app.js
index d124b58..bed7e84 100644
--- a/frontend/static/app.js
+++ b/frontend/static/app.js
@@ -1257,6 +1257,12 @@ const CamSettings = {
`` +
`` +
`` +
+ ` | ` +
+ `` +
+ (cam
+ ? ` ` +
+ ``
+ : "") +
` | `
);
},
@@ -1328,7 +1334,7 @@ const CamSettings = {
const v = (x) => this.esc(x);
const isEdit = !!cam;
return (
- `` +
+ ` | ` +
` ` +
`` +
`` +
@@ -1444,7 +1450,8 @@ const CamSettings = {
` | | ` +
` | ` +
` | ` +
- `${statusCell} | `;
+ `${statusCell} | ` +
+ ` | `;
tb.appendChild(tr);
} else {
tr.className = "slot-empty";
@@ -1452,7 +1459,8 @@ const CamSettings = {
tr.innerHTML =
`${i + 1} | ` +
`— | — | — | — | — | — | ` +
- `пусто | `;
+ `пусто | ` +
+ ` | `;
tb.appendChild(tr);
}
}
@@ -1473,9 +1481,14 @@ const CamSettings = {
} else if (act === "delete") {
this.remove(id, this.byId[id] ? this.byId[id].name : id);
} else if (act === "restart") {
- btn.disabled = true; btn.textContent = "…";
+ const prev = btn.textContent; btn.disabled = true; btn.textContent = "…";
await post(`/api/cameras/${id}/restart`);
- setTimeout(() => this.load(), 1500);
+ if (this.bulk) { // в массовом режиме строки не перерисовываем (правки не теряем)
+ btn.textContent = "✓";
+ setTimeout(() => { btn.textContent = prev; btn.disabled = false; }, 1500);
+ } else {
+ setTimeout(() => this.load(), 1500);
+ }
} else if (act === "log") {
const box = document.getElementById("log-" + id);
if (!box.hidden) { box.hidden = true; return; }
diff --git a/frontend/static/style.css b/frontend/static/style.css
index a9436a8..73176bc 100644
--- a/frontend/static/style.css
+++ b/frontend/static/style.css
@@ -425,9 +425,25 @@ table.cams th, table.cams td {
table.cams th { color: var(--text-dim); font-weight: 500; font-size: 11px; padding: 4px 10px; }
table.cams td.actions { white-space: nowrap; text-align: right; }
table.cams tr.slot-empty td { opacity: .5; }
-/* камеры: жёстко фиксированная высота строки 22px (плотная таблица) */
+/* камеры: жёстко фиксированная высота строки 22px независимо от контролов.
+ line-height:1 + контролы по центру и ниже 22px → строки не распирает. */
table.cams.cams-fixed td, table.cams.cams-fixed th {
- height: 22px; padding-top: 0; padding-bottom: 0; line-height: 22px;
+ height: 22px; padding-top: 0; padding-bottom: 0; line-height: 1;
+}
+table.cams.cams-fixed td > * { vertical-align: middle; }
+/* тумблеры «Вкл»/«Запись» в строке — компактные (30×16) */
+table.cams.cams-fixed td input[type="checkbox"] {
+ width: 30px; height: 16px; border-radius: 8px;
+}
+table.cams.cams-fixed td input[type="checkbox"]::before { width: 12px; height: 12px; top: 1px; left: 1px; }
+table.cams.cams-fixed td input[type="checkbox"]:checked::before { transform: translateX(14px); }
+/* селекты и инпуты в строке — на 2px ниже строки, по центру */
+table.cams.cams-fixed td select.stor-sel,
+table.cams.cams-fixed td select.cell-sel,
+table.cams.cams-fixed td input.cell-in { height: 20px; }
+/* кнопки действий ⟳/✕ (режим редактирования) — компактные */
+table.cams.cams-fixed td.actions button {
+ height: 20px; padding: 0 6px; font-size: 13px; line-height: 1;
}
/* ── Инлайн-редактор строки (вместо всплывающего окна) ── */