Stabilize project flows and reporting
This commit is contained in:
+35
-19
@@ -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", "업데이트 재시도 중");
|
||||
|
||||
Reference in New Issue
Block a user