diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab.ts b/M01_MasterData/M01_MasterData_UI_LogicLab.ts index 6780f3a45..319f5f606 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab.ts @@ -6,7 +6,7 @@ * * 데이터 흐름(CLAUDE.md 5장) — 고친 것은 캐시(sessionStorage)에 쌓고 [저장] 한 번에 `POST /save`. * 409 = 그 사이 파일이 바뀜 · 422 = 검사 걸림(아무것도 안 씀) — 까닭은 서버 글 그대로 보임. - * 머리 단추(804-7 · 요구 687-2) = [신규 로직] · [로직 복사/생성] · [로직 삭제] · [되돌림] · [저장] + * 머리 단추(804-7 · 요구 687-2) = [신규 로직] · [로직 복사/생성] · [로직 삭제] · [되돌림] · [저장] · 목록에선 [신규 로직]만(요구 693) * [저장] = 기본정보 · 별칭(로직 줄 `/save`) + 수식(줄 쌓기 `/logic/doc/save`) 한 번에 · [되돌림] = 둘 다 저장 뒤 상태로 * [로직 삭제] = 확인 → 서버 정본에서 바로(`/logic/remove` — 로직 줄 + 수식 문서 · 부르는 곳 있으면 막고 까닭) → 로직 목록 * ========================================================================== */ @@ -234,6 +234,8 @@ export async function mountM01LogicLab( waiting.hidden = loaded; panes.root.hidden = !opened; back.hidden = views.root.hidden = listing; + // 로직을 골라야 뜻 있는 단추 = 목록에선 숨김(요구 693 · [신규 로직]만 보임) + copyButton.hidden = deleteButton.hidden = discardButton.hidden = saveButton.hidden = listing; if (!opened) return; if (!opened.row) { editor.replaceChildren(createEmpty({ text: `● ${tx("List_Deleted")}`, small: true })); @@ -528,6 +530,12 @@ export async function mountM01LogicLab( }) : showToast(tl("Copy_NeedOpen"), "info"), }); + const deleteButton = createButton({ + label: tx("Bar_Delete"), + variant: "danger", + iconStart: "trash", + onClick: () => void onDelete(), + }); // 제목 줄 = 요소 화면(인력 · 재료 …)과 같은 공용 조각 const bar = buildHeadBar({ lead: [back], @@ -542,12 +550,7 @@ export async function mountM01LogicLab( onClick: () => void onNew(), }), copyButton, - createButton({ - label: tx("Bar_Delete"), - variant: "danger", - iconStart: "trash", - onClick: () => void onDelete(), - }), + deleteButton, discardButton, saveButton, ], diff --git a/M02_MasterTemplete/M02_MasterTemplete_UI_Style.css b/M02_MasterTemplete/M02_MasterTemplete_UI_Style.css index 9ae1c3acc..674704b72 100644 --- a/M02_MasterTemplete/M02_MasterTemplete_UI_Style.css +++ b/M02_MasterTemplete/M02_MasterTemplete_UI_Style.css @@ -103,6 +103,11 @@ html.is-bm-route .m02-main__head { min-height: 240px; } +/* 원문 손잡이 = 브라우저 오른쪽 끝(요구 694 · M01 687-17 과 같은 규칙) — 메인 칸 오른쪽 여백(24)만큼 밀어 붙임 · 본문이 그 자리까지 */ +html:not([data-size="compact"], [data-size="medium"]) .m02-main__host > .ui-side-panels-row { + margin-inline-end: calc(-1 * var(--spacing-24)); +} + /* 면적산출 · 재료산출 전체 편집 — `.ss` 는 height:100% 로 부모 높이를 받음 · 도면 편집과 같이 메인 칸을 화면 높이로 채움 */ .m02-main:has(> .m02-main__host > .ss) { box-sizing: border-box; diff --git a/resources/tester/test_804_11_list_buttons.py b/resources/tester/test_804_11_list_buttons.py new file mode 100644 index 000000000..0222d6a13 --- /dev/null +++ b/resources/tester/test_804_11_list_buttons.py @@ -0,0 +1,38 @@ +"""804-11(요구 693 · 694) — M01 목록 화면 머리 단추 · M02 원문 손잡이 오른쪽 끝. + +① M01 단가산출 기초 목록 = [신규 로직]만 · 로직을 열면 [로직 복사/생성] · [로직 삭제] · [되돌림] · [저장] 나타남(숨김 · 흐림 아님) + 요소 묶음(인력 · 재료 · 유가 · 기계 · 소요량 · 계수 · 환율 · 요율) · 구조물 옵션 정의 · 별칭 장부 = 항목 고름에 매인 머리 단추 없음(그대로) +② M02 원문 손잡이 = M01(804-7 · 687-17)과 같은 규칙 — 메인 칸 오른쪽 여백만큼 밀어 붙임(단가산출 · 일위대가 등 `m02-main__host` 바로 아래 칸) +""" + +from __future__ import annotations + +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] + + +def _src(rel: str) -> str: + return (ROOT / rel).read_text(encoding="utf-8") + + +def test_M01_목록_머리_단추_숨김() -> None: + lab = _src("M01_MasterData/M01_MasterData_UI_LogicLab.ts") + line = "copyButton.hidden = deleteButton.hidden = discardButton.hidden = saveButton.hidden = listing;" + assert line in lab + at = lab.index("const drawEditor = (): void => {") + assert at < lab.index(line) < lab.index("if (!opened) return;", at) # 목록 갈래 return 앞 + assert ( + " copyButton,\n deleteButton,\n discardButton,\n saveButton," + in lab.replace("\r\n", "\n") + ) + + +def test_M02_원문_손잡이_오른쪽_끝() -> None: + css = _src("M02_MasterTemplete/M02_MasterTemplete_UI_Style.css") + m02 = ".m02-main__host > .ui-side-panels-row {\n margin-inline-end: calc(-1 * var(--spacing-24));" + assert m02 in css.replace("\r\n", "\n") + assert "padding: var(--spacing-16) var(--spacing-24);" in css # 민 만큼 = 메인 칸 오른쪽 여백 + m01 = _src("M01_MasterData/M01_MasterData_UI_LogicLab_Side.css") + cond = 'html:not([data-size="compact"], [data-size="medium"])' + assert f"{cond} .m02-main__host" in css and f"{cond} .m01-master__panel" in m01 # 같은 조건 diff --git a/resources/tester/test_m02_layer_screen.py b/resources/tester/test_m02_layer_screen.py index 058103778..0209a2715 100644 --- a/resources/tester/test_m02_layer_screen.py +++ b/resources/tester/test_m02_layer_screen.py @@ -315,7 +315,7 @@ def test_구조물_조합_제목_줄_새_항목(): main = _text(M02 / "M02_MasterTemplete_UI_Main.ts") assert "export function newItemButton(" in main and 'classList.add("m02-main__new")' in main assert re.search( - r"children: \[\s*back,\s*title,\s*nav\.root,\s*helpSlot,\s*slot,\s*reload,\s*actions\.reset,\s*actions\.del,\s*save," + r"children: \[\s*back,\s*title,\s*nav\.root,\s*helpSlot,\s*slot,\s*reload,\s*actions\.reset,\s*actions\.del,\s*actions\.undo,\s*save," r"\s*\.\.\.\(extras\.newItem \? \[extras\.newItem\] : \[\]\),?\s*\]", main, )