fix(772-1): ☰ 서랍 진행 단계 · 바로가기 칸 빠짐 — 진행 판 공용 자리에서 맡김 · 안 맡긴 쪽 기본 목록
- 까닭: B03 파일입력 = 진행 판을 직접 조립(createWorkflowOverlays)해 서랍 맡김(setDrawerSteps)이 빠짐 ·
B02 · B10 · B11 · D01 · E01 = 일반 판이라 맡기는 쪽이 없음 · B01 = 10-26 새 틀(e505f4014)에서 옛 ☰ 구역 바로가기를 걷음
- 진행 판(createWorkflowOverlays)이 progressContent 를 받으면 서랍에 맡김 — 워크플로 판 · B03 한 자리
- ☰ 를 열 때 맡긴 목록이 없으면 기본 목록 = 🏠 대시보드 + 권한별 M01 · M02(mountSettingsDrawer 와 같은 한 벌) · 늦게 온 쪽 목록이 이김
- 터치 켬 서랍 진행 단계 줄 40 → 44(옆 규칙이 더 세어 덮던 것)
- 시험: helper_280_2 의 app_shell 대역은 workflow_layout 이 더는 안 불러 지움 · helper_359_2 에 overlay 용 대역 더함 · test_772_1 새로
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+12
-3
@@ -133,7 +133,7 @@ function buildBrand(): HTMLButtonElement {
|
||||
* 서랍을 열 때 서랍으로 옮기고 닫을 때 제자리(진행 판)로 — 그리기 · 누름 코드는 한 벌. */
|
||||
let drawerSteps: { node: HTMLElement; home: HTMLElement | null } | null = null;
|
||||
|
||||
/** 집(진행 판) 없는 요소 = 서랍이 늘 가짐 · 닫을 때 안 옮김(B01 · M01 · M02 바로가기) */
|
||||
/** 집(진행 판) 없는 요소 = 서랍이 늘 가짐 · 닫을 때 안 옮김(M01 · M02 바로가기 · 기본 목록) */
|
||||
export function setDrawerSteps(node: HTMLElement | null): void {
|
||||
drawerSteps = node ? { node, home: node.parentElement } : null;
|
||||
}
|
||||
@@ -178,11 +178,20 @@ function buildDrawer(header: HTMLElement): HTMLElement[] {
|
||||
const setOpen = (open: boolean): void => {
|
||||
header.classList.toggle("is-drawer-open", open);
|
||||
burger.setAttribute("aria-expanded", String(open));
|
||||
if (open && !drawerSteps) void fillDefaultSteps();
|
||||
if (!drawerSteps) return;
|
||||
if (open) steps.append(drawerSteps.node);
|
||||
if (open)
|
||||
steps.replaceChildren(drawerSteps.node); // 앞서 맡은 기본 목록이 있으면 갈아 끼움
|
||||
else if (drawerSteps.home && steps.contains(drawerSteps.node))
|
||||
drawerSteps.home.append(drawerSteps.node);
|
||||
};
|
||||
// 진행 판 · 바로가기를 안 맡긴 쪽(772-1) = 기본 목록(🏠 대시보드 + 권한별 M01 · M02) · 늦게 온 쪽 목록이 이김
|
||||
const fillDefaultSteps = async (): Promise<void> => {
|
||||
const bar = await import("./m_settings_nav").then((m) => m.defaultSettingsBar());
|
||||
if (!bar || drawerSteps || !steps.isConnected) return;
|
||||
setDrawerSteps(bar);
|
||||
if (header.classList.contains("is-drawer-open")) steps.replaceChildren(bar);
|
||||
};
|
||||
burger.addEventListener("click", () => setOpen(!header.classList.contains("is-drawer-open")));
|
||||
scrim.addEventListener("click", () => setOpen(false));
|
||||
header.addEventListener("keydown", (e) => e.key === "Escape" && setOpen(false)); // ☰ 에 포커스가 있어도 닫힘
|
||||
@@ -485,7 +494,7 @@ html:is([data-burger="on"], .is-bm-route) .app-burger { display: inline-flex; }
|
||||
.app-drawer__steps .ui-workflow-layout__steps.is-vertical .ui-workflow-layout__step { min-height: var(--spacing-40); margin-inline: 8px; width: auto; padding-left: 7px; }
|
||||
.app-drawer :is(.ui-btn__label, .ui-workflow-layout__step-label) { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.app-drawer__steps .ui-workflow-layout__step--home { margin-bottom: 0; }
|
||||
html[data-touch="on"] :is(.app-drawer__nav > *, .app-drawer__site > summary, .app-drawer__steps .ui-workflow-layout__step, .app-drawer__row > *) { min-height: 44px; }
|
||||
html[data-touch="on"] :is(.app-drawer__nav > *, .app-drawer__site > summary, .app-drawer__steps .ui-workflow-layout__steps.is-vertical .ui-workflow-layout__step, .app-drawer__row > *) { min-height: 44px; }
|
||||
.app-drawer__row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/* =============================================================================
|
||||
* m_settings_nav.ts
|
||||
* 시스템 설정 바로가기(334 · 요구 225-2 · 716-2) — 대시보드 설계 기본값 줄(`settingLinks` · 칸마다 한 줄 ·
|
||||
* `?open=`) / M01 · M02 ☰ 메뉴(`pageLinks` · 페이지 둘 · `mountSettingsDrawer`).
|
||||
* `?open=`) / M01 · M02 ☰ 메뉴(`pageLinks` · 페이지 둘 · `mountSettingsDrawer`) /
|
||||
* 진행 판 없는 쪽 ☰ 기본 목록(`defaultSettingsBar` · 772-1).
|
||||
* ========================================================================== */
|
||||
|
||||
import { ROUTES, type RoutePath } from "@config/config_frontend";
|
||||
@@ -112,8 +113,24 @@ export function mountSettingsDrawer(
|
||||
activeKey: string,
|
||||
companyId: number | string | null,
|
||||
): void {
|
||||
setDrawerSteps(settingsBar(user, activeKey, companyId));
|
||||
}
|
||||
|
||||
/** ☰ 기본 목록(772-1) — 진행 판 · 바로가기를 안 세운 로그인 뒤 쪽(B02 · D01 · E01 등) = 🏠 대시보드 + 권한별 페이지 둘 ·
|
||||
* 로그인 전 = 없음 */
|
||||
export async function defaultSettingsBar(): Promise<HTMLElement | null> {
|
||||
const { fetchSessionUser } = await import("../A06_Login/A06_Login_Api_Fetch");
|
||||
const user = await fetchSessionUser().catch(() => null);
|
||||
return user ? settingsBar(user, "", null) : null;
|
||||
}
|
||||
|
||||
function settingsBar(
|
||||
user: SettingUser,
|
||||
activeKey: string,
|
||||
companyId: number | string | null,
|
||||
): HTMLElement {
|
||||
const links = pageLinks(user, companyId);
|
||||
const bar = createStepBar(
|
||||
return createStepBar(
|
||||
links.map((link) => link.title),
|
||||
links.findIndex((link) => link.key === activeKey),
|
||||
{
|
||||
@@ -124,7 +141,6 @@ export function mountSettingsDrawer(
|
||||
onStepClick: (index) => void go(links[index]),
|
||||
},
|
||||
);
|
||||
setDrawerSteps(bar);
|
||||
}
|
||||
|
||||
async function go(link: SettingLink): Promise<void> {
|
||||
|
||||
@@ -156,7 +156,6 @@ const STUBS = {
|
||||
},
|
||||
},
|
||||
"../A00_Common/router": { navigateTo: () => undefined },
|
||||
"../A00_Common/app_shell": { setDrawerSteps: () => undefined },
|
||||
"../B01_Dashboard/B01_Dashboard_Api_Fetch": { fetchDashboardMe: async () => ({ role }) },
|
||||
};
|
||||
globalThis.__DEV = false;
|
||||
|
||||
@@ -107,6 +107,7 @@ const { loadTs } = makeLoader({
|
||||
"/b_workflow_nav": { fetchWorkflowState: async () => ({}) },
|
||||
"/b_page_state": { readByKey: () => null, writeByKey: () => undefined },
|
||||
"/device_context": { SIZE_BREAKS: { expanded: 840 } },
|
||||
"/app_shell": { setDrawerSteps: () => undefined },
|
||||
},
|
||||
});
|
||||
const overlay = loadTs(path.join(ROOT, "ui_template", "ui_template_overlay.ts"));
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
"""772-1 ☰ 서랍 진행 단계 · 바로가기 칸 — 진행 판을 세우는 공용 자리 한 곳에서 맡김 · 안 맡긴 쪽은 기본 목록."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def _text(rel: str) -> str:
|
||||
return (ROOT / rel).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_진행_판을_세우면_서랍에_맡김():
|
||||
overlay = _text("ui_template/ui_template_overlay.ts")
|
||||
body = overlay.split("export function createWorkflowOverlays")[1]
|
||||
assert (
|
||||
"setDrawerSteps(options.progressContent)" in body.split("if (options.progressContent)")[1]
|
||||
)
|
||||
# 워크플로 판 · B03 은 진행 판(overlay)에만 맡김 — 따로 부르면 두 번
|
||||
assert "setDrawerSteps" not in _text("ui_template/ui_template_workflow_layout.ts")
|
||||
assert "setDrawerSteps" not in _text("B03_FileInput/B03_FileInput_UI_Page.ts")
|
||||
assert "createWorkflowOverlays" in _text("B03_FileInput/B03_FileInput_UI_Page.ts")
|
||||
|
||||
|
||||
def test_안_맡긴_쪽은_기본_목록():
|
||||
shell = _text("A00_Common/app_shell.ts")
|
||||
set_open = shell.split("const setOpen")[1].split("};")[0]
|
||||
assert "if (open && !drawerSteps) void fillDefaultSteps();" in set_open
|
||||
assert "steps.replaceChildren(drawerSteps.node)" in set_open
|
||||
fill = shell.split("const fillDefaultSteps")[1].split("};")[0]
|
||||
assert (
|
||||
"defaultSettingsBar()" in fill
|
||||
and "if (!bar || drawerSteps || !steps.isConnected) return;" in fill
|
||||
)
|
||||
nav = _text("A00_Common/m_settings_nav.ts")
|
||||
default = nav.split("export async function defaultSettingsBar")[1].split("\n}")[0]
|
||||
assert "fetchSessionUser" in default and 'settingsBar(user, "", null)' in default
|
||||
# M01 · M02 와 같은 한 벌(pageLinks · createStepBar · 🏠)
|
||||
bar = nav.split("function settingsBar")[1]
|
||||
assert "pageLinks(user, companyId)" in bar and "homeButton: true" in bar
|
||||
@@ -22,6 +22,7 @@ import { fetchWorkflowState } from "../A00_Common/b_workflow_nav";
|
||||
import { currentProjectId } from "../A00_Common/b_project_switch";
|
||||
import { readByKey, writeByKey } from "../A00_Common/b_page_state";
|
||||
import { SIZE_BREAKS } from "../A00_Common/device_context";
|
||||
import { setDrawerSteps } from "../A00_Common/app_shell";
|
||||
|
||||
const TITLE_OVERLAY_STATE_KEY = "frd_workflow_title_overlay_open";
|
||||
const PROGRESS_OVERLAY_STATE_KEY = "frd_workflow_progress_overlay_open";
|
||||
@@ -294,6 +295,8 @@ export function createWorkflowOverlays(options: WorkflowOverlayOptions): Workflo
|
||||
if (options.progressContent) {
|
||||
const progressBody = document.createElement("div");
|
||||
progressBody.append(options.progressContent);
|
||||
// ☰ 서랍 진행 단계 묶음(6-2 · 772-1) — 진행 판을 세우는 모든 화면(워크플로 판 · B03)이 같은 목록을 서랍에 빌려 줌
|
||||
setDrawerSteps(options.progressContent);
|
||||
const progressPanel = createPanel(
|
||||
"progress",
|
||||
t("Workflow_Progress_Title"),
|
||||
|
||||
@@ -14,7 +14,6 @@ import { t } from "./ui_template_locale";
|
||||
import { createWorkflowOverlays } from "./ui_template_overlay";
|
||||
import { showToast } from "./ui_template_elements";
|
||||
import { navigateTo } from "../A00_Common/router";
|
||||
import { setDrawerSteps } from "../A00_Common/app_shell";
|
||||
import { fetchDashboardMe } from "../B01_Dashboard/B01_Dashboard_Api_Fetch";
|
||||
|
||||
let dashboardRolePromise: Promise<string> | undefined;
|
||||
@@ -243,8 +242,6 @@ export function createWorkflowLayout(options: WorkflowLayoutOptions): WorkflowLa
|
||||
});
|
||||
|
||||
root.append(body, overlays.root);
|
||||
// ☰ 서랍 진행 단계 묶음(6-2) — 같은 단계 목록을 서랍이 열릴 때 빌려 감(그리기 · 누름 한 벌)
|
||||
setDrawerSteps(progressContent);
|
||||
const steps = [
|
||||
...progressContent.querySelectorAll<HTMLElement>(
|
||||
".ui-workflow-layout__step:not(.ui-workflow-layout__step--home)",
|
||||
|
||||
Reference in New Issue
Block a user