fix: complete catalog pagination and recovery states

This commit is contained in:
2026-09-11 11:25:59 +03:00
parent 78493b9248
commit a82930027d
13 changed files with 296 additions and 52 deletions

View File

@@ -61,8 +61,8 @@
text-underline-offset: 4px;
}
:is(a, button, input, select):focus-visible {
outline: 3px solid #14b8a6;
:is(a, button, input, select, summary):focus-visible {
outline: 3px solid #0f766e;
outline-offset: 2px;
}
@@ -133,10 +133,6 @@
border-collapse: collapse;
}
.table__row {
cursor: pointer;
}
.table__row:hover {
background: #f0fdfa;
}
@@ -205,6 +201,19 @@
.button--compact {
padding: 8px 12px;
}
.button:hover {
filter: brightness(0.9);
}
.button:active {
filter: brightness(0.8);
}
.button:disabled {
cursor: wait;
opacity: 0.65;
}
.code {
@@ -537,7 +546,7 @@
.directory__filters {
display: grid;
grid-template-columns: 1.1fr 2fr 1.25fr 2fr;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
padding: 16px;
background: #ffffff;
@@ -547,7 +556,7 @@
.directory__filter-group {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
grid-template-columns: 1fr;
align-content: start;
gap: 8px;
min-width: 0;
@@ -578,6 +587,9 @@
}
.directory__input {
font: inherit;
font-size: 16px;
font-weight: 400;
min-width: 0;
padding: 10px 12px;
border: 1px solid #cbd5e1;
@@ -611,9 +623,18 @@
font-weight: 700;
}
.directory__help {
color: #4b5563;
line-height: 1.5;
}
.directory__help summary {
cursor: pointer;
}
.directory-table {
width: 100%;
min-width: 960px;
min-width: 640px;
border-collapse: collapse;
}
@@ -628,10 +649,15 @@
}
.directory-table__cell {
overflow-wrap: anywhere;
max-width: 280px;
padding: 12px 10px;
border-bottom: 1px solid #e5e7eb;
vertical-align: top;
}
.directory-table .badge {
white-space: nowrap;
}
.directory-table__row {
@@ -751,6 +777,14 @@
}
@media (max-width: 620px) {
.directory-table [data-column="full_name"] {
position: sticky;
left: 0;
z-index: 1;
min-width: 130px;
max-width: 160px;
background: #ffffff;
}
.admin__header {
align-items: flex-start;
padding: 16px;
@@ -780,11 +814,3 @@
font-size: 13px;
}
}
@media (prefers-reduced-motion: no-preference) {
.progress-bar__fill {
transition-property: width;
transition-duration: 0.25s;
transition-timing-function: ease;
}
}

View File

@@ -3,11 +3,7 @@
"full_name",
"status",
"positions",
"hse_start_year",
"email",
"academic_degree",
"last_seen_at",
"dismissed_at",
"profile",
];
const storageKey = "miem.directory.columns";
@@ -85,6 +81,11 @@
function setupProgress() {
const panel = document.querySelector("[data-progress-panel]");
if (!panel) return;
const state = document.createElement("p");
state.className = "progress-panel__empty";
state.setAttribute("role", "status");
panel.append(state);
let pending = false;
const update = (run) => {
if (!run) return;
@@ -111,17 +112,31 @@
};
const poll = async () => {
if (pending) return true;
pending = true;
state.textContent = "Обновляем прогресс…";
panel.setAttribute("aria-busy", "true");
try {
const response = await fetch("/api/crawl-runs/latest", { credentials: "same-origin" });
const response = await fetch("/api/crawl-runs/latest", {
credentials: "same-origin",
signal: AbortSignal.timeout(15000),
});
if (!response.ok) throw new Error("progress request failed");
const data = await response.json();
const run = data.running || data.latest;
update(run);
state.textContent = run ? "Прогресс обновлён" : "Запусков пока нет. Запустите парсинг.";
const error = document.querySelector("[data-progress-error]");
if (error) error.hidden = true;
return Boolean(data.running);
} catch (_error) {
const error = document.querySelector("[data-progress-error]");
if (error) error.hidden = false;
state.textContent = "Показаны последние полученные данные. Прогресс может быть устаревшим.";
return true;
} finally {
pending = false;
panel.setAttribute("aria-busy", "false");
}
};