Журнал: пагинация 30 записей на страницу, API offset/total_pages
- job_journal: collect_recent_journal_entries_page_sync(limit, offset) - GET /api/v1/journal/recent: limit по умолчанию 30, offset, total, page, total_pages - journal.html/js: навигация Первая/Назад/номера/Вперёд/Последняя, стили - app/docs/api_routes.md: описание query и пример ответа - Прочие изменения UI/API (аддоны, helm, job_journal в кластерах) в том же коммите
This commit is contained in:
@@ -189,6 +189,50 @@
|
||||
if (el) el.classList.add("hidden");
|
||||
}
|
||||
|
||||
function isJobLogModalOpen() {
|
||||
const el = document.getElementById("job-log-modal-overlay");
|
||||
return !!(el && !el.classList.contains("hidden"));
|
||||
}
|
||||
|
||||
function closeJobLogModal() {
|
||||
const el = document.getElementById("job-log-modal-overlay");
|
||||
if (el) el.classList.add("hidden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Открыть модалку с текстовым журналом завершённого задания (GET /jobs/{id}).
|
||||
* @param {string} jobId
|
||||
*/
|
||||
function openJobLogModal(jobId) {
|
||||
const overlay = document.getElementById("job-log-modal-overlay");
|
||||
const sub = document.getElementById("job-log-modal-sub");
|
||||
const pre = document.getElementById("job-log-modal-body");
|
||||
const titleEl = document.getElementById("job-log-modal-title");
|
||||
if (!overlay || !pre) return;
|
||||
pre.textContent = "Загрузка журнала…";
|
||||
if (sub) sub.textContent = "Задание: " + jobId;
|
||||
if (titleEl) titleEl.textContent = "Журнал задания";
|
||||
overlay.classList.remove("hidden");
|
||||
api("/jobs/" + encodeURIComponent(jobId))
|
||||
.then(function (job) {
|
||||
if (titleEl) {
|
||||
titleEl.textContent =
|
||||
"Журнал задания · " + (job.status || "") + (job.kind ? " · " + job.kind : "");
|
||||
}
|
||||
if (sub) {
|
||||
var parts = ["Задание: " + jobId];
|
||||
if (job.cluster_name) parts.push("Кластер: " + job.cluster_name);
|
||||
if (job.message) parts.push(job.message);
|
||||
sub.textContent = parts.join(" · ");
|
||||
}
|
||||
var lines = job.progress_log || [];
|
||||
pre.textContent = lines.length ? lines.join("\n") : job.message || "(журнал пуст)";
|
||||
})
|
||||
.catch(function (e) {
|
||||
pre.textContent = "Не удалось загрузить журнал: " + (e && e.message ? e.message : String(e));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Загрузить ``GET /clusters/{name}/provision-log`` и показать JSON в модалке.
|
||||
* @param {string} clusterName
|
||||
@@ -1760,6 +1804,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Один раз: кнопка «Журнал» в таблице последних заданий открывает модалку (не сбрасывается при автообновлении списка).
|
||||
*/
|
||||
function bindJobsTableJobLogOpen() {
|
||||
const tbl = document.getElementById("tbl-jobs");
|
||||
if (!tbl || tbl.getAttribute("data-jobs-job-log-bound") === "1") return;
|
||||
tbl.setAttribute("data-jobs-job-log-bound", "1");
|
||||
tbl.addEventListener(
|
||||
"click",
|
||||
function (ev) {
|
||||
const btn = ev.target && ev.target.closest ? ev.target.closest("button.jobs-open-log-btn") : null;
|
||||
if (!btn || !tbl.contains(btn)) return;
|
||||
const jobId = btn.getAttribute("data-job-id");
|
||||
if (!jobId) return;
|
||||
ev.preventDefault();
|
||||
openJobLogModal(jobId);
|
||||
},
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
async function loadJobs() {
|
||||
const tbody = document.querySelector("#tbl-jobs tbody");
|
||||
const msg = document.getElementById("jobs-msg");
|
||||
@@ -1782,6 +1847,14 @@
|
||||
j.progress_stage +
|
||||
(j.progress_percent != null ? " (" + j.progress_percent + "%)" : "");
|
||||
}
|
||||
var msgCol =
|
||||
"<div class=\"jobs-msg-primary\">" + escapeHtml(cellMsg) + "</div>";
|
||||
if (j.status === "failed" || j.status === "cancelled") {
|
||||
msgCol +=
|
||||
"<button type=\"button\" class=\"btn-secondary jobs-open-log-btn\" data-job-id=\"" +
|
||||
escapeHtml(j.job_id || "") +
|
||||
"\">Журнал</button>";
|
||||
}
|
||||
const iso = j.created_at_utc || "";
|
||||
const timeLabel = formatJobTimeUtc(iso);
|
||||
tr.innerHTML =
|
||||
@@ -1801,7 +1874,7 @@
|
||||
st +
|
||||
"</span></td>" +
|
||||
"<td class=\"jobs-msg-cell\">" +
|
||||
escapeHtml(cellMsg) +
|
||||
msgCol +
|
||||
"</td>";
|
||||
frag.appendChild(tr);
|
||||
});
|
||||
@@ -2324,6 +2397,10 @@
|
||||
});
|
||||
}
|
||||
|
||||
if (document.getElementById("tbl-jobs")) {
|
||||
bindJobsTableJobLogOpen();
|
||||
}
|
||||
|
||||
const mClose = document.getElementById("modal-close");
|
||||
if (mClose) mClose.addEventListener("click", closeModal);
|
||||
|
||||
@@ -2340,6 +2417,10 @@
|
||||
closeConfirmModal(confirmModalIsAlert ? true : false);
|
||||
return;
|
||||
}
|
||||
if (isJobLogModalOpen()) {
|
||||
closeJobLogModal();
|
||||
return;
|
||||
}
|
||||
if (isProvisionLogModalOpen()) {
|
||||
closeProvisionLogModal();
|
||||
return;
|
||||
@@ -2378,6 +2459,17 @@
|
||||
});
|
||||
}
|
||||
|
||||
const jobLogOv = document.getElementById("job-log-modal-overlay");
|
||||
const jobLogClose = document.getElementById("job-log-modal-close");
|
||||
if (jobLogClose) {
|
||||
jobLogClose.addEventListener("click", closeJobLogModal);
|
||||
}
|
||||
if (jobLogOv) {
|
||||
jobLogOv.addEventListener("click", function (ev) {
|
||||
if (ev.target === jobLogOv) closeJobLogModal();
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener(
|
||||
"scroll",
|
||||
function () {
|
||||
@@ -2419,6 +2511,7 @@
|
||||
}
|
||||
bindActionTooltipHosts(document.getElementById("modal-overlay"));
|
||||
bindActionTooltipHosts(document.getElementById("provision-log-modal-overlay"));
|
||||
bindActionTooltipHosts(document.getElementById("job-log-modal-overlay"));
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
|
||||
Reference in New Issue
Block a user