diff --git a/cmd/creator-web/server_test.go b/cmd/creator-web/server_test.go index 4108322..b8482cf 100644 --- a/cmd/creator-web/server_test.go +++ b/cmd/creator-web/server_test.go @@ -239,6 +239,11 @@ func TestConsoleAndSecurityHeaders(t *testing.T) { !strings.Contains(response.Body.String(), "К содержимому") || !strings.Contains(response.Body.String(), "aria-current=\"location\"") || !strings.Contains(response.Body.String(), "section-nav-link") || + !strings.Contains(response.Body.String(), "data-page=\"overview\"") || + !strings.Contains(response.Body.String(), "data-page=\"diagnostics\"") || + !strings.Contains(response.Body.String(), "data-page=\"operations\"") || + !strings.Contains(response.Body.String(), "data-page=\"learning\"") || + !strings.Contains(response.Body.String(), "data-page=\"settings\"") || !strings.Contains(response.Body.String(), "satisfaction-dialog") || !strings.Contains(response.Body.String(), "Подтверждаю переход") || !strings.Contains(response.Body.String(), "action-history") || !strings.Contains(response.Body.String(), "Журнал действий") || !strings.Contains(response.Body.String(), "advisory-form") || !strings.Contains(response.Body.String(), "Спросить Домового") || diff --git a/cmd/creator-web/static/assets/console.css b/cmd/creator-web/static/assets/console.css index ad7115a..5f8ec60 100644 --- a/cmd/creator-web/static/assets/console.css +++ b/cmd/creator-web/static/assets/console.css @@ -123,6 +123,7 @@ button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus- .session-stamp strong { overflow: hidden; color: var(--muted); font: 10px/1.4 var(--mono); text-overflow: ellipsis; } .workspace { grid-column: 2; grid-row: 2; width: min(100%, 1740px); justify-self: start; padding: 42px clamp(24px, 3vw, 48px) 64px; min-width: 0; } +.workspace > [data-page][hidden] { display: none !important; } .workspace > section { scroll-margin-top: 94px; } .workspace-head { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 34px; } .workspace-head h1 { margin: 0; font: 400 clamp(34px, 4vw, 50px)/1 var(--serif); letter-spacing: -.035em; } diff --git a/cmd/creator-web/static/assets/console.js b/cmd/creator-web/static/assets/console.js index 4a1536d..517b092 100644 --- a/cmd/creator-web/static/assets/console.js +++ b/cmd/creator-web/static/assets/console.js @@ -20,37 +20,29 @@ let lastAuthorizedActionID = ""; let advisoryPolicy = {Mode: "deterministic", ExternalEgress: false, AcknowledgementRequired: false}; let uiSettings = {density: "comfortable", refresh: "off", motion: false}; -const sectionNavLinks = Array.from(document.querySelectorAll(".section-nav-link")); -const cabinetSections = ["overview", "diagnostics", "operations", "learning", "settings"] - .map((id) => byId(id)) - .filter(Boolean); +const pageNavLinks = Array.from(document.querySelectorAll(".section-nav-link, .topbar-nav a")); +const pageViews = Array.from(document.querySelectorAll("[data-page]")); +const cabinetPages = ["overview", "diagnostics", "operations", "learning", "settings"]; -function setActiveSection(id) { - sectionNavLinks.forEach((link) => { - const active = link.getAttribute("href") === `#${id}`; +function setActivePage(id, updateHistory = false) { + const page = cabinetPages.includes(id) ? id : "overview"; + pageViews.forEach((view) => { view.hidden = view.dataset.page !== page; }); + document.body.dataset.page = page; + pageNavLinks.forEach((link) => { + const active = link.getAttribute("href") === `#${page}`; link.classList.toggle("active", active); if (active) link.setAttribute("aria-current", "location"); else link.removeAttribute("aria-current"); }); + if (updateHistory && window.location.hash !== `#${page}`) window.history.pushState({}, "", `#${page}`); } -if ("IntersectionObserver" in window) { - const sectionObserver = new IntersectionObserver((entries) => { - const visible = entries.filter((entry) => entry.isIntersecting) - .sort((a, b) => b.intersectionRatio - a.intersectionRatio)[0]; - if (visible) setActiveSection(visible.target.id); - }, {rootMargin: "-18% 0px -64% 0px", threshold: [0, .25, .6, 1]}); - cabinetSections.forEach((section) => sectionObserver.observe(section)); -} - -sectionNavLinks.forEach((link) => link.addEventListener("click", () => { - const id = link.getAttribute("href").slice(1); - setActiveSection(id); +pageNavLinks.forEach((link) => link.addEventListener("click", (event) => { + event.preventDefault(); + setActivePage(link.getAttribute("href").slice(1), true); })); -window.addEventListener("hashchange", () => { - const id = window.location.hash.slice(1); - if (cabinetSections.some((section) => section.id === id)) setActiveSection(id); -}); +window.addEventListener("popstate", () => setActivePage(window.location.hash.slice(1))); +setActivePage(window.location.hash.slice(1)); function setText(id, value, fallback = "—") { byId(id).textContent = value === undefined || value === null || value === "" ? fallback : String(value); diff --git a/cmd/creator-web/static/index.html b/cmd/creator-web/static/index.html index 68687c4..c09047c 100644 --- a/cmd/creator-web/static/index.html +++ b/cmd/creator-web/static/index.html @@ -113,7 +113,7 @@
-
+

операционная картина

Состояние сейчас

@@ -121,14 +121,14 @@

Данные ещё не запрошены

-
+
ФОКУСожидает
ЗАДАЧАожидает
CONTINUITYожидает
ВОЗМОЖНОСТЬожидает
-
+

Проверяемая система

Диагностика кабинета

Проверка ещё не запускалась
@@ -142,7 +142,7 @@
-
+

COGNITIVE / ADVISORY V1

Спросить Домового

@@ -170,7 +170,7 @@
-
+

Continuity / ближайшие

Реестр ожиданий

0 ЗАПИСЕЙ @@ -180,7 +180,7 @@
-
+

Commit / владелец

Журнал действий

@@ -193,7 +193,7 @@
-
+

Learning / evidence

Опыт и reflection

@@ -217,7 +217,7 @@
-
+

Локальные предпочтения

Настройки рабочего кабинета

Сохраняются в этом браузере @@ -230,7 +230,7 @@
-
+
01

Situation

Активный фокус

НЕ ЗАГРУЖЕН
diff --git a/dev/ACTIVE_TASK.json b/dev/ACTIVE_TASK.json index 4a3925e..0c64490 100644 --- a/dev/ACTIVE_TASK.json +++ b/dev/ACTIVE_TASK.json @@ -1,5 +1,5 @@ { "task_file": "dev/tasks/DEV-000074-creator-cabinet-operations.json", "task_id": "DEV-000074", - "task_revision": 5 + "task_revision": 6 } diff --git a/dev/tasks/DEV-000074-creator-cabinet-operations.json b/dev/tasks/DEV-000074-creator-cabinet-operations.json index cbbb42e..a8dde82 100644 --- a/dev/tasks/DEV-000074-creator-cabinet-operations.json +++ b/dev/tasks/DEV-000074-creator-cabinet-operations.json @@ -1,8 +1,8 @@ { "task_id": "DEV-000074", - "task_revision": 5, + "task_revision": 6, "architecture_revision": "DEV-000073-baseline", - "base_repo_revision": "dcdc9a2e645e6c34551dc66d98c05220abaf5244", + "base_repo_revision": "1cfbb4ae66e24d514e59dabafb936c35546bd418", "risk_tier": "E", "intent": "Make the authenticated Creator Web cabinet understandable and operable for a human by adding section navigation, read-only diagnostics, and browser-local interface preferences without changing domain state or authority boundaries.", "requirement_ids": [