Stabilize project flows and reporting

This commit is contained in:
b17301
2026-04-09 21:01:21 +09:00
parent f2d86cd840
commit 9aaae5b820
11 changed files with 5118 additions and 626 deletions
+35 -19
View File
@@ -17,6 +17,9 @@
--warn: #fff2cb;
--table-alt: #f5f6f8;
--white: #ffffff;
--page-gutter: clamp(14px, 1.8vw, 24px);
--panel-pad: clamp(16px, 1.4vw, 20px);
--page-frame-width: min(1520px, calc(100vw - (var(--page-gutter) * 2)));
}
* {
@@ -32,14 +35,18 @@
radial-gradient(circle at top left, rgba(255, 255, 255, 0.92), transparent 24%),
linear-gradient(180deg, var(--bg-a), var(--bg-b));
min-height: 100vh;
padding: 14px;
padding: var(--page-gutter);
}
.page {
max-width: 1520px;
width: min(100%, var(--page-frame-width));
margin: 0 auto;
display: grid;
gap: 14px;
gap: var(--page-gutter);
}
.page > * {
width: 100%;
}
.nav {
@@ -82,7 +89,7 @@
background: var(--panel);
border: 1px solid var(--line);
border-radius: 18px;
padding: 18px;
padding: var(--panel-pad);
box-shadow: 0 10px 24px rgba(21, 24, 29, 0.045);
backdrop-filter: blur(6px);
}
@@ -450,10 +457,6 @@
}
@media (max-width: 720px) {
body {
padding: 14px;
}
.stats,
.form-grid {
grid-template-columns: 1fr;
@@ -484,6 +487,7 @@
id="syncStatusWidget"
data-data-version="{{ data_version or '' }}"
data-refresh-url="{{ request.url.path }}{% if request.url.query %}?{{ request.url.query }}{% endif %}"
data-refresh-mode="{{ 'disabled' if request.url.path == '/projects' else 'auto' }}"
>
<div class="sync-status-head">
<div class="sync-status-title">
@@ -521,6 +525,7 @@
const dataVersion = document.getElementById("syncDataVersion");
let pageVersion = widget.dataset.dataVersion || "";
const refreshUrl = widget.dataset.refreshUrl || window.location.href;
const refreshMode = widget.dataset.refreshMode || "auto";
let refreshInFlight = false;
let pendingVersion = "";
let isFormDirty = false;
@@ -536,6 +541,7 @@
}
const clientSessionId = getSessionId();
window.clientSessionId = clientSessionId;
sessionPill.textContent = clientSessionId;
function updateWidgetTitle() {
@@ -591,17 +597,36 @@
updateWidgetTitle();
}
function setPageDataVersion(nextVersion) {
pageVersion = nextVersion || "";
pendingVersion = "";
widget.dataset.dataVersion = pageVersion;
dataVersion.textContent = pageVersion || "-";
updateWidgetTitle();
}
window.__setPageDataVersion = setPageDataVersion;
function hasActiveEditor() {
const active = document.activeElement;
return Boolean(active && active.closest && active.closest("form[data-collab-form]"));
}
function hasOpenModal() {
return Boolean(document.querySelector(".modal-backdrop.open"));
}
function shouldDelayRefresh() {
return isFormDirty || hasActiveEditor();
return isFormDirty || hasActiveEditor() || hasOpenModal() || window.__suspendAutoRefresh === true;
}
async function refreshPageWhenSafe(nextVersion) {
if (refreshInFlight) return;
if (refreshMode === "disabled") {
setPageDataVersion(nextVersion || pageVersion);
setStatus("online", "서버 정상 연결");
return;
}
if (shouldDelayRefresh()) {
pendingVersion = nextVersion || pendingVersion || pageVersion;
setStatus("online", "새 데이터 대기 중");
@@ -613,16 +638,7 @@
setStatus("online", "새 데이터 반영 중");
try {
const response = await fetch(refreshUrl, {
cache: "no-store",
credentials: "same-origin",
headers: { "X-Requested-With": "XMLHttpRequest" },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const html = await response.text();
document.open();
document.write(html);
document.close();
window.location.replace(refreshUrl);
} catch (error) {
refreshInFlight = false;
setStatus("error", "업데이트 재시도 중");